class_docstr: Base class for a forecaster model.
  
  .. note::
  
      If your model depends on an evenly spaced time series, make sure to
  
      1. Call `ForecasterBase.train_pre_process` in `ForecasterBase.train`
      2. Call `ForecasterBase.resample_time_stamps` at the start of
         `ForecasterBase.forecast` to get a set of resampled time stamps, and
         call ``time_series.align(reference=time_stamps)`` to align the forecast
         with the original time stamps.
class_docstr_tok: ["Base","class","for","a","forecaster","model",".","..","note",":",":","If","your","model","depends","on","an","evenly","spaced","time","series",",","make","sure","to","1",".","Call","`","ForecasterBase.train_pre_process","`","in","`","ForecasterBase.train","`","2",".","Call","`","ForecasterBase.resample_time_stamps","`","at","the","start","of","`","ForecasterBase.forecast","`","to","get","a","set","of","resampled","time","stamps",",","and","call","``","time_series.align","(","reference=time_stamps",")","``","to","align","the","forecast","with","the","original","time","stamps","."]
code: def train_pre_process(
      self,
      train_data: TimeSeries,
      exog_data: TimeSeries = None,
      return_exog=None,
  ) -> Union[TimeSeries, Tuple[TimeSeries, Union[TimeSeries, None]]]:
      train_data = super().train_pre_process(train_data)
  
      if self.dim == 1:
          self.config.target_seq_index = 0
      elif (
          self.target_seq_index is None
          and not self.support_multivariate_output
      ):
          raise RuntimeError(
              f"Attempting to use a forecaster that does not support multivariate outputs "
              f"on a {train_data.dim}-variable "
              f"time series, but didn't specify a `target_seq_index` "
              f"indicating which univariate is the target."
          )
  
      assert self.support_multivariate_output or (
          0 <= self.target_seq_index < train_data.dim
      ), (
          f"Expected `support_multivariate_output = True`,"
          f"or `target_seq_index` to be between 0 and {train_data.dim}"
          f"(the dimension of the transformed data), but got {self.target_seq_index} "
      )
  
      if (
          self.support_multivariate_output
          and self.target_seq_index is None
      ):
          self.target_name = str(train_data.names)
      else:
          self.target_name = train_data.names[self.target_seq_index]
  
      # Handle exogenous data
      if return_exog is None:
          return_exog = exog_data is not None
      if not self.supports_exog:
          if exog_data is not None:
              exog_data = None
              logger.warning(
                  f"Exogenous regressors are not supported for model {type(self).__name__}"
              )
      if exog_data is not None:
          self.exog_dim = exog_data.dim
          self.config.exog_transform.train(exog_data)
      else:
          self.exog_dim = None
      if return_exog and exog_data is not None:
          exog_data, _ = self.transform_exog_data(
              exog_data=exog_data, time_stamps=train_data.time_stamps
          )
      return (train_data, exog_data) if return_exog else train_data
  
imports: from abc import abstractmethod
  import copy
  import logging
  from typing import List, Optional, Tuple, Union
  import numpy
  import pandas
  from scipy.stats import norm
  from merlion.models.base import Config, ModelBase
  from merlion.plot import Figure
  from merlion.transform.base import TransformBase
  from merlion.transform.factory import TransformFactory
  from merlion.transform.normalize import MeanVarNormalize
  from merlion.utils.time_series import to_pd_datetime, to_timestamp, TimeSeries, AggregationPolicy, MissingValuePolicy
label_desc: Use image node_id 8 for calling the ForecasterBase obj's underlying member method code with example usage: obj.train_pre_process(train_data, exog_data, return_exog) and returns: unknown