code: def multitrait_inf(mt, h2=None, rg=None, cov_matrix=None, seed=None):
      r"""Generates correlated betas for multi-trait infinitesimal simulations for
      any number of phenotypes.
  
      Parameters
      ----------
      mt : :class:`.MatrixTable`
          MatrixTable for simulated phenotype.
      h2 : :obj:`float` or :obj:`int` or :obj:`list` or :class:`numpy.ndarray`, optional
          Desired SNP-based heritability (:math:`h^2`) of simulated traits.
          If `h2` is ``None``, :math:`h^2` is based on diagonal of `cov_matrix`.
      rg : :obj:`float` or :obj:`int` or :obj:`list` or :class:`numpy.ndarray`, optional
          Desired genetic correlation (:math:`r_g`) between simulated traits.
          If simulating more than two correlated traits, `rg` should be a list
          of :math:`rg` values corresponding to the upper right triangle of the
          covariance matrix. If `rg` is ``None`` and `cov_matrix` is ``None``, :math:`r_g`
          is assumed to be 0 between traits. If `rg` and `cov_matrix` are both
          not None, :math:`r_g` values from `cov_matrix` take precedence.
      cov_matrix : :class:`numpy.ndarray`, optional
          Covariance matrix for traits, **unscaled by :math:`M`**, the number of SNPs.
          Overrides `h2` and `rg` even when `h2` or `rg` are not ``None``.
      seed : :obj:`int`, optional
          Seed for random number generator. If `seed` is ``None``, `seed` is set randomly.
  
      Returns
      -------
      mt : :class:`.MatrixTable`
          :class:`.MatrixTable` with simulated SNP effects as a row field of arrays.
      rg : :obj:`list`
          Genetic correlation between traits, possibly altered from input `rg` if
          covariance matrix was not positive semi-definite.
      """
      uid = Env.get_uid(base=100)
      h2 = (
          h2.tolist()
          if isinstance(h2, np.ndarray)
          else ([h2] if not isinstance(h2, list) else h2)
      )
      rg = (
          rg.tolist()
          if isinstance(rg, np.ndarray)
          else ([rg] if not isinstance(rg, list) else rg)
      )
      assert all(
          x >= 0 and x <= 1 for x in h2
      ), "h2 values must be between 0 and 1"
      assert (
          h2 is not [None] or cov_matrix is not None
      ), "h2 and cov_matrix cannot both be None"
      M = mt.count_rows()
      if cov_matrix is not None:
          n_phens = cov_matrix.shape[0]
      else:
          n_phens = len(h2)
          if rg == [None]:
              print(f"Assuming rg=0 for all {n_phens} traits")
              rg = [0] * int((n_phens**2 - n_phens) / 2)
          assert all(
              x >= -1 and x <= 1 for x in rg
          ), "rg values must be between 0 and 1"
          cov, rg = get_cov_matrix(h2, rg)
      cov = (1 / M) * cov
      # seed random state for replicability
      randstate = np.random.RandomState(int(seed))
      betas = randstate.multivariate_normal(
          mean=np.zeros(n_phens),
          cov=cov,
          size=[
              M,
          ],
      )
      df = pd.DataFrame([0] * M, columns=["beta"])
      tb = hl.Table.from_pandas(df)
      tb = tb.add_index().key_by("idx")
      tb = tb.annotate(
          beta=hl.literal(betas.tolist())[hl.int32(tb.idx)]
      )
      mt = mt.add_row_index(name="row_idx" + uid)
      mt = mt.annotate_rows(beta=tb[mt["row_idx" + uid]]["beta"])
      mt = _clean_fields(mt, uid)
      return mt, rg
  
imports: import hail
  from hail.typecheck import typecheck, oneof, nullable
  from hail.expr.expressions import expr_float64, expr_int32, expr_array, expr_call
  from hail.matrixtable import MatrixTable
  from hail.table import Table
  from hail.utils.java import Env
  import numpy
  import pandas
  import scipy.stats
label_desc: Use image node_id 3 for calling a global function with example usage: multitrait_inf(mt, h2, rg, cov_matrix, seed) and returns: mt,  rg