<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def make_model_sources_image(shape, model, source_table, oversample=1):
 """ Make an image containing sources generated from a user-specified model. Parameters shape : 2-tuple of int The shape of the output 2D image. model : 2D astropy.modeling.models object The model to be used for rendering the sources. source_table : `~astropy.table.Table` Table of parameters for the sources. Each row of the table corresponds to a source whose model parameters are defined by the column names, which must match the model parameter names. Column names that do not match model parameters will be ignored. Model parameters not defined in the table will be set to the ``model`` default value. oversample : float, optional The sampling factor used to discretize the models on a pixel grid. If the value is 1.0 (the default), then the models will be discretized by taking the value at the center of the pixel bin. Note that this method will not preserve the total flux of very small sources. Otherwise, the models will be discretized by taking the average over an oversampled grid. The pixels will be oversampled by the ``oversample`` factor. Returns ------- image : 2D `~numpy.ndarray` Image containing model sources. See Also -------- make_random_models_table, make_gaussian_sources_image Examples -------- .. plot:: :include-source: from collections import OrderedDict from astropy.modeling.models import Moffat2D from photutils.datasets import (make_random_models_table, make_model_sources_image) model = Moffat2D() n_sources = 10 shape = (100, 100) param_ranges = [('amplitude', [100, 200]), ('x_0', [0, shape[1]]), ('y_0', [0, shape[0]]), ('gamma', [5, 10]), ('alpha', [1, 2])] param_ranges = OrderedDict(param_ranges) sources = make_random_models_table(n_sources, param_ranges, random_state=12345) data = make_model_sources_image(shape, model, sources) plt.imshow(data) """


    image = np.zeros(shape, dtype=np.float64)
    y, x = np.indices(shape)

    params_to_set = []
    for param in source_table.colnames:
        if param in model.param_names:
            params_to_set.append(param)

    # Save the initial parameter values so we can set them back when
    # done with the loop.  It's best not to copy a model, because some
    # models (e.g. PSF models) may have substantial amounts of data in
    # them.
    init_params = {param: getattr(model, param) for param in params_to_set}

    try:
        for i, source in enumerate(source_table):
            for param in params_to_set:
                setattr(model, param, source[param])

            if oversample == 1:
                image += model(x, y)
            else:
                image += discretize_model(model, (0, shape[1]),
                                          (0, shape[0]), mode='oversample',
                                          factor=oversample)
    finally:
        for param, value in init_params.items():
            setattr(model, param, value)

    return image