class_docstr: Base Recurrent
  
  Base class for all recurrent-based models. The forecasts are produced sequentially between
  windows.
  
  This class implements the basic functionality for all windows-based models, including:
  - PyTorch Lightning's methods training_step, validation_step, predict_step. <br>
  - fit and predict methods used by NeuralForecast.core class. <br>
  - sampling and wrangling methods to sequential windows. <br>
class_docstr_tok: ["Base","Recurrent","Base","class","for","all","recurrent-based","models",".","The","forecasts","are","produced","sequentially","between","windows",".","This","class","implements","the","basic","functionality","for","all","windows-based","models",",","including",":","-","PyTorch","Lightning","'s","methods","training_step",",","validation_step",",","predict_step",".","<","br",">","-","fit","and","predict","methods","used","by","NeuralForecast.core","class",".","<","br",">","-","sampling","and","wrangling","methods","to","sequential","windows",".","<","br",">"]
code: def _create_windows(self, batch, step):
      temporal = batch["temporal"]
      temporal_cols = batch["temporal_cols"]
  
      if step == "train":
          if self.val_size + self.test_size > 0:
              cutoff = -self.val_size - self.test_size
              temporal = temporal[:, :, :cutoff]
          temporal = self.padder(temporal)
  
          # Truncate batch to shorter time-series
          av_condition = torch.nonzero(
              torch.min(
                  temporal[:, temporal_cols.get_loc("available_mask")],
                  axis=0,
              ).values
          )
          min_time_stamp = int(av_condition.min())
  
          available_ts = temporal.shape[-1] - min_time_stamp
          if available_ts < 1 + self.h:
              raise Exception(
                  "Time series too short for given input and output size. \n"
                  f"Available timestamps: {available_ts}"
              )
  
          temporal = temporal[:, :, min_time_stamp:]
  
      if step == "val":
          if self.test_size > 0:
              temporal = temporal[:, :, : -self.test_size]
          temporal = self.padder(temporal)
  
      if step == "predict":
          if (self.test_size == 0) and (len(self.futr_exog_list) == 0):
              temporal = self.padder(temporal)
  
          # Test size covers all data, pad left one timestep with zeros
          if temporal.shape[-1] == self.test_size:
              padder_left = nn.ConstantPad1d(padding=(1, 0), value=0)
              temporal = padder_left(temporal)
  
      # Parse batch
      window_size = 1 + self.h  # 1 for current t and h for future
      windows = temporal.unfold(dimension=-1, size=window_size, step=1)
  
      # Truncated backprogatation/inference (shorten sequence where RNNs unroll)
      n_windows = windows.shape[2]
      input_size = -1
      if (step == "train") and (self.input_size > 0):
          input_size = self.input_size
          if (input_size > 0) and (n_windows > input_size):
              max_sampleable_time = n_windows - self.input_size + 1
              start = np.random.choice(max_sampleable_time)
              windows = windows[:, :, start : (start + input_size), :]
  
      if (step == "val") and (self.inference_input_size > 0):
          cutoff = self.inference_input_size + self.val_size
          windows = windows[:, :, -cutoff:, :]
  
      if (step == "predict") and (self.inference_input_size > 0):
          cutoff = self.inference_input_size + self.test_size
          windows = windows[:, :, -cutoff:, :]
  
      # [B, C, input_size, 1+H]
      windows_batch = dict(
          temporal=windows,
          temporal_cols=temporal_cols,
          static=batch.get("static", None),
          static_cols=batch.get("static_cols", None),
      )
  
      return windows_batch
  
imports: import random
  import warnings
  import numpy
  import torch
  import torch.nn
  import pytorch_lightning
  from pytorch_lightning.callbacks import TQDMProgressBar
  from pytorch_lightning.callbacks.early_stopping import EarlyStopping
  from ._scalers import TemporalNorm
  from ..tsdataset import TimeSeriesDataModule
  from ..utils import get_indexer_raise_missing
label_desc: Use image node_id 8 for calling the BaseRecurrent obj's underlying member method code with example usage: obj._create_windows(batch, step) and returns: windows_batch