code: def test_transforms(self, infer_noise: bool = False):
      tkwargs = {"device": self.device, "dtype": torch.double}
      (
          train_X,
          train_Y,
          train_Yvar,
          test_X,
      ) = self._get_unnormalized_data(**tkwargs)
      n, d = train_X.shape
      normalize_indices = torch.tensor(
          list(range(train_X.shape[-1] - 1)), **{"device": self.device}
      )
  
      lb, ub = (
          train_X[:, normalize_indices].min(dim=0).values,
          train_X[:, normalize_indices].max(dim=0).values,
      )
      train_X_new = train_X.clone()
      train_X_new[..., normalize_indices] = (
          train_X[..., normalize_indices] - lb
      ) / (ub - lb)
      # TODO: add testing of stratified standardization
      mu, sigma = train_Y.mean(), train_Y.std()
  
      # Fit without transforms
      with torch.random.fork_rng():
          torch.manual_seed(0)
          gp1 = SaasFullyBayesianMultiTaskGP(
              train_X=train_X_new,
              train_Y=(train_Y - mu) / sigma,
              train_Yvar=None
              if infer_noise
              else train_Yvar / sigma**2,
              task_feature=d - 1,
          )
          fit_fully_bayesian_model_nuts(
              gp1,
              warmup_steps=8,
              num_samples=5,
              thinning=2,
              disable_progbar=True,
          )
      posterior1 = gp1.posterior(
          (test_X - lb) / (ub - lb), output_indices=[0]
      )
      pred_mean1 = mu + sigma * posterior1.mean
      pred_var1 = (sigma**2) * posterior1.variance
  
      # Fit with transforms
      with torch.random.fork_rng():
          torch.manual_seed(0)
          gp2 = SaasFullyBayesianMultiTaskGP(
              train_X=train_X,
              train_Y=train_Y,
              train_Yvar=None if infer_noise else train_Yvar,
              task_feature=d - 1,
              input_transform=Normalize(
                  d=train_X.shape[-1], indices=normalize_indices
              ),
              outcome_transform=Standardize(m=1),
          )
          fit_fully_bayesian_model_nuts(
              gp2,
              warmup_steps=8,
              num_samples=5,
              thinning=2,
              disable_progbar=True,
          )
          posterior2 = gp2.posterior(X=test_X, output_indices=[0])
          pred_mean2, pred_var2 = posterior2.mean, posterior2.variance
  
      self.assertAllClose(pred_mean1, pred_mean2)
      self.assertAllClose(pred_var1, pred_var2)
  
imports: import itertools
  from typing import List, Optional
  import torch
  from botorch import fit_fully_bayesian_model_nuts
  from botorch.acquisition.analytic import ExpectedImprovement, PosteriorMean, ProbabilityOfImprovement, UpperConfidenceBound
  from botorch.acquisition.monte_carlo import qExpectedImprovement, qNoisyExpectedImprovement, qProbabilityOfImprovement, qSimpleRegret, qUpperConfidenceBound
  from botorch.acquisition.multi_objective import qExpectedHypervolumeImprovement, qNoisyExpectedHypervolumeImprovement
  from botorch.models import ModelList, ModelListGP
  from botorch.models.deterministic import GenericDeterministicModel
  from botorch.models.fully_bayesian import MCMC_DIM, MIN_INFERRED_NOISE_LEVEL
  from botorch.models.fully_bayesian_multitask import MultitaskSaasPyroModel, SaasFullyBayesianMultiTaskGP
  from botorch.models.transforms.input import Normalize
  from botorch.models.transforms.outcome import Standardize
  from botorch.posteriors import GaussianMixturePosterior
  from botorch.sampling.get_sampler import get_sampler
  from botorch.sampling.normal import IIDNormalSampler
  from botorch.utils.multi_objective.box_decompositions.non_dominated import NondominatedPartitioning
  from botorch.utils.test_helpers import gen_multi_task_dataset
  from botorch.utils.testing import BotorchTestCase
  from gpytorch.kernels import MaternKernel, ScaleKernel
  from gpytorch.likelihoods import FixedNoiseGaussianLikelihood
  from gpytorch.likelihoods.gaussian_likelihood import GaussianLikelihood
  from gpytorch.means import ConstantMean
label_desc: Use image node_id 8 for calling the TestFullyBayesianMultiTaskGP obj's underlying member method code with example usage: obj.test_transforms(infer_noise) without return types