docs: def make_random_gaussians_table(n_sources, param_ranges, random_state=None):
      """
      Make a `~astropy.table.Table` containing randomly generated
      parameters for 2D Gaussian sources.
  
      Each row of the table corresponds to a Gaussian source whose
      parameters are defined by the column names.  The parameters are
      drawn from a uniform distribution over the specified input ranges.
  
      The output table can be input into
      :func:`make_gaussian_sources_image` to create an image containing
      the 2D Gaussian sources.
  
      Parameters
      ----------
      n_sources : float
          The number of random Gaussian sources to generate.
  
      param_ranges : dict
          The lower and upper boundaries for each of the
          `~astropy.modeling.functional_models.Gaussian2D` parameters as a
          `dict` mapping the parameter name to its ``(lower, upper)``
          bounds.  The dictionary keys must be valid
          `~astropy.modeling.functional_models.Gaussian2D` parameter names
          or ``'flux'``.  If ``'flux'`` is specified, but not
          ``'amplitude'`` then the 2D Gaussian amplitudes will be
          calculated and placed in the output table.  If both ``'flux'``
          and ``'amplitude'`` are specified, then ``'flux'`` will be
          ignored.  Model parameters not defined in ``param_ranges`` will
          be set to the default value.
  
      random_state : int or `~numpy.random.RandomState`, optional
          Pseudo-random number generator state used for random sampling.
  
      Returns
      -------
      table : `~astropy.table.Table`
          A table of parameters for the randomly generated Gaussian
          sources.  Each row of the table corresponds to a Gaussian source
          whose parameters are defined by the column names.
  
      See Also
      --------
      make_random_models_table, make_gaussian_sources_image
  
      Notes
      -----
      To generate identical parameter values from separate function calls,
      ``param_ranges`` must be input as an `~collections.OrderedDict` with
      the same parameter ranges and ``random_state`` must be the same.
  
  
      Examples
      --------
      >>> from collections import OrderedDict
      >>> from photutils.datasets import make_random_gaussians_table
      >>> n_sources = 5
      >>> param_ranges = [('amplitude', [500, 1000]),
      ...                 ('x_mean', [0, 500]),
      ...                 ('y_mean', [0, 300]),
      ...                 ('x_stddev', [1, 5]),
      ...                 ('y_stddev', [1, 5]),
      ...                 ('theta', [0, np.pi])]
      >>> param_ranges = OrderedDict(param_ranges)
      >>> sources = make_random_gaussians_table(n_sources, param_ranges,
      ...                                       random_state=12345)
      >>> for col in sources.colnames:
      ...     sources[col].info.format = '%.8g'  # for consistent table output
      >>> print(sources)
      amplitude   x_mean    y_mean   x_stddev  y_stddev   theta
      --------- --------- --------- --------- --------- ----------
      964.80805 297.77235 224.31444 3.6256447 3.5699013  2.2923859
      658.18778 482.25726 288.39202 4.2392502 3.8698145  3.1227889
      591.95941 326.58855 2.5164894 4.4887037  2.870396  2.1264615
      602.28014 374.45332 31.933313 4.8585904 2.3023387  2.4844422
      783.86251 326.78494 89.611114 3.8947414 2.7585784 0.53694298
  
      To specifying the flux range instead of the amplitude range:
  
      >>> param_ranges = [('flux', [500, 1000]),
      ...                 ('x_mean', [0, 500]),
      ...                 ('y_mean', [0, 300]),
      ...                 ('x_stddev', [1, 5]),
      ...                 ('y_stddev', [1, 5]),
      ...                 ('theta', [0, np.pi])]
      >>> param_ranges = OrderedDict(param_ranges)
      >>> sources = make_random_gaussians_table(n_sources, param_ranges,
      ...                                       random_state=12345)
      >>> for col in sources.colnames:
      ...     sources[col].info.format = '%.8g'  # for consistent table output
      >>> print(sources)
         flux     x_mean    y_mean   x_stddev  y_stddev   theta    amplitude
      --------- --------- --------- --------- --------- ---------- ---------
      964.80805 297.77235 224.31444 3.6256447 3.5699013  2.2923859 11.863685
      658.18778 482.25726 288.39202 4.2392502 3.8698145  3.1227889 6.3854388
      591.95941 326.58855 2.5164894 4.4887037  2.870396  2.1264615 7.3122209
      602.28014 374.45332 31.933313 4.8585904 2.3023387  2.4844422 8.5691781
      783.86251 326.78494 89.611114 3.8947414 2.7585784 0.53694298 11.611707
  
      Note that in this case the output table contains both a flux and
      amplitude column.  The flux column will be ignored when generating
      an image of the models using :func:`make_gaussian_sources_image`.
      """
  
      sources = make_random_models_table(n_sources, param_ranges,
                                         random_state=random_state)
  
      # convert Gaussian2D flux to amplitude
      if 'flux' in param_ranges and 'amplitude' not in param_ranges:
          model = Gaussian2D(x_stddev=1, y_stddev=1)
  
          if 'x_stddev' in sources.colnames:
              xstd = sources['x_stddev']
          else:
              xstd = model.x_stddev.value    # default
          if 'y_stddev' in sources.colnames:
              ystd = sources['y_stddev']
          else:
              ystd = model.y_stddev.value    # default
  
          sources = sources.copy()
          sources['amplitude'] = sources['flux'] / (2. * np.pi * xstd * ystd)
  
      return sources