docs: def Normalize(self, period, start_time, stop_time, mode=NORMALIZE_MODE_GAUGE):
      """Normalize the series to have a fixed period over a fixed time range.
  
      Supports two modes, depending on the type of data:
  
        NORMALIZE_MODE_GAUGE: support gauge values. If multiple original data
          points lie within an output interval, the output value is an average of
          the original data point.  if no original data points lie within an
          output interval, the output value is None.
  
        NORMALIZE_MODE_COUNTER: supports counter values. Assumes that the sequence
          is already increasing (typically, MakeIncreasing will have been
          called). Each output value is the largest value seen during or before
          the corresponding output interval.
  
      Args:
  
        period: The desired time between points. Should be an rdfvalue.Duration or
          a count of microseconds.
  
        start_time: The first timestamp will be at start_time. Should be an
          rdfvalue.RDFDatetime or a count of microseconds since epoch.
  
        stop_time: The last timestamp will be at stop_time - period. Should be an
          rdfvalue.RDFDatetime or a count of microseconds since epoch.
  
        mode: The type of normalization to perform. May be NORMALIZE_MODE_GAUGE or
          NORMALIZE_MODE_COUNTER.
  
      Raises:
        RuntimeError: In case the sequence timestamps are misordered.
  
      """
      period = self._NormalizeTime(period)
      start_time = self._NormalizeTime(start_time)
      stop_time = self._NormalizeTime(stop_time)
      if not self.data:
        return
  
      self.FilterRange(start_time, stop_time)
  
      grouped = {}
      for value, timestamp in self.data:
        offset = timestamp - start_time
        shifted_offset = offset - (offset % period)
        grouped.setdefault(shifted_offset, []).append(value)
  
      self.data = []
      last_value = None
      for offset in range(0, stop_time - start_time, period):
        g = grouped.get(offset)
        if mode == NORMALIZE_MODE_GAUGE:
          v = None
          if g:
            v = sum(g) / len(g)
          self.data.append([v, offset + start_time])
        else:
          if g:
            for v in g:
              if v < last_value:
                raise RuntimeError("Next value must not be smaller.")
              last_value = v
          self.data.append([last_value, offset + start_time])