class_docstr: Mixin for behavior shared by Downsampled{Factor,Filter,Classifier}
  
  A downsampled term is a wrapper around the "real" term that performs actual
  computation. The downsampler is responsible for calling the real term's
  `compute` method at selected intervals and forward-filling the computed
  values.
  
  Downsampling is not currently supported for terms with multiple outputs.
docstr: Ensure that min_extra_rows pushes us back to a computation date.
  
  Parameters
  ----------
  all_dates : pd.DatetimeIndex
      The trading sessions against which ``self`` will be computed.
  start_date : pd.Timestamp
      The first date for which final output is requested.
  end_date : pd.Timestamp
      The last date for which final output is requested.
  min_extra_rows : int
      The minimum number of extra rows required of ``self``, as
      determined by other terms that depend on ``self``.
  
  Returns
  -------
  extra_rows : int
      The number of extra rows to compute.  This will be the minimum
      number of rows required to make our computed start_date fall on a
      recomputation date.
docstr_tok: ["Ensure","that","min_extra_rows","pushes","us","back","to","a","computation","date",".","Parameters","--","--","--","--","--","all_dates",":","pd.DatetimeIndex","The","trading","sessions","against","which","``","self","``","will","be","computed",".","start_date",":","pd.Timestamp","The","first","date","for","which","final","output","is","requested",".","end_date",":","pd.Timestamp","The","last","date","for","which","final","output","is","requested",".","min_extra_rows",":","int","The","minimum","number","of","extra","rows","required","of","``","self","``",",","as","determined","by","other","terms","that","depend","on","``","self","``",".","Returns","--","--","--","-","extra_rows",":","int","The","number","of","extra","rows","to","compute",".","This","will","be","the","minimum","number","of","rows","required","to","make","our","computed","start_date","fall","on","a","recomputation","date","."]
code: def compute_extra_rows(
      self, all_dates, start_date, end_date, min_extra_rows
  ):
      """
      Ensure that min_extra_rows pushes us back to a computation date.
  
      Parameters
      ----------
      all_dates : pd.DatetimeIndex
          The trading sessions against which ``self`` will be computed.
      start_date : pd.Timestamp
          The first date for which final output is requested.
      end_date : pd.Timestamp
          The last date for which final output is requested.
      min_extra_rows : int
          The minimum number of extra rows required of ``self``, as
          determined by other terms that depend on ``self``.
  
      Returns
      -------
      extra_rows : int
          The number of extra rows to compute.  This will be the minimum
          number of rows required to make our computed start_date fall on a
          recomputation date.
      """
      try:
          current_start_pos = (
              all_dates.get_loc(start_date) - min_extra_rows
          )
          if current_start_pos < 0:
              raise NoFurtherDataError(
                  initial_message="Insufficient data to compute Pipeline:",
                  first_date=all_dates[0],
                  lookback_start=start_date,
                  lookback_length=min_extra_rows,
              )
      except KeyError:
          before, after = nearest_unequal_elements(
              all_dates, start_date
          )
          raise ValueError(
              "Pipeline start_date {start_date} is not in calendar.\n"
              "Latest date before start_date is {before}.\n"
              "Earliest date after start_date is {after}.".format(
                  start_date=start_date,
                  before=before,
                  after=after,
              )
          )
  
      # Our possible target dates are all the dates on or before the current
      # starting position.
      # TODO: Consider bounding this below by self.window_length
      candidates = all_dates[: current_start_pos + 1]
  
      # Choose the latest date in the candidates that is the start of a new
      # period at our frequency.
      choices = select_sampling_indices(candidates, self._frequency)
  
      # If we have choices, the last choice is the first date if the
      # period containing current_start_date.  Choose it.
      new_start_date = candidates[choices[-1]]
  
      # Add the difference between the new and old start dates to get the
      # number of rows for the new start_date.
      new_start_pos = all_dates.get_loc(new_start_date)
      assert (
          new_start_pos <= current_start_pos
      ), "Computed negative extra rows!"
  
      return min_extra_rows + (current_start_pos - new_start_pos)
  
imports: from textwrap import dedent
  from numpy import array, full, recarray, vstack
  from pandas import NaT
  from catalyst.errors import WindowLengthNotPositive, UnsupportedDataType, NoFurtherDataError
  from catalyst.utils.control_flow import nullctx
  from catalyst.utils.input_validation import expect_types
  from catalyst.utils.sharedoc import format_docstring, PIPELINE_ALIAS_NAME_DOC, PIPELINE_DOWNSAMPLING_FREQUENCY_DOC
  from catalyst.utils.pandas_utils import nearest_unequal_elements
  from .downsample_helpers import select_sampling_indices, expect_downsample_frequency
  from .sentinels import NotSpecified
  from .term import Term
label_desc: Use image node_id 4 for calling the DownsampledMixin obj's underlying member method code with example usage: obj.compute_extra_rows(all_dates, start_date, end_date, min_extra_rows) and returns: unknown