<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _generate_noise_system(dimensions_tr, spatial_sd, temporal_sd, spatial_noise_type='gaussian', temporal_noise_type='gaussian', ):
 """Generate the scanner noise Generate system noise, either rician, gaussian or exponential, for the scanner. Generates a distribution with a SD of 1. If you look at the distribution of non-brain voxel intensity in modern scans you will see it is rician. However, depending on how you have calculated the SNR and whether the template is being used you will want to use this function differently: the voxels outside the brain tend to be stable over time and usually reflect structure in the MR signal (e.g. the baseline MR of the head coil or skull). Hence the template captures this rician noise structure. If you are adding the machine noise to the template, as is done in generate_noise, then you are likely doubling up on the addition of machine noise. In such cases, machine noise seems to be better modelled by gaussian noise on top of this rician structure. Parameters dimensions_tr : n length array, int What are the dimensions of the volume you wish to insert noise into. This can be a volume of any size spatial_sd : float What is the standard deviation in space of the noise volume to be generated temporal_sd : float What is the standard deviation in time of the noise volume to be generated noise_type : str String specifying the noise type. If you aren't specifying the noise template then Rician is the appropriate model of noise. However, if you are subtracting the template, as is default, then you should use gaussian. (If the dilation parameter of _calc_snr is <10 then gaussian is only an approximation) Returns system_noise : multidimensional array, float Create a volume with system noise """

    def noise_volume(dimensions,
                     noise_type,
                     ):

        if noise_type == 'rician':
            # Generate the Rician noise (has an SD of 1)
            noise = stats.rice.rvs(b=0, loc=0, scale=1.527, size=dimensions)
        elif noise_type == 'exponential':
            # Make an exponential distribution (has an SD of 1)
            noise = stats.expon.rvs(0, scale=1, size=dimensions)
        elif noise_type == 'gaussian':
            noise = np.random.randn(np.prod(dimensions)).reshape(dimensions)

        # Return the noise
        return noise

    # Get just the xyz coordinates
    dimensions = np.asarray([dimensions_tr[0],
                             dimensions_tr[1],
                             dimensions_tr[2],
                             1])

    # Generate noise
    spatial_noise = noise_volume(dimensions, spatial_noise_type)
    temporal_noise = noise_volume(dimensions_tr, temporal_noise_type)

    # Make the system noise have a specific spatial variability
    spatial_noise *= spatial_sd

    # Set the size of the noise
    temporal_noise *= temporal_sd

    # The mean in time of system noise needs to be zero, so subtract the
    # means of the temporal noise in time
    temporal_noise_mean = np.mean(temporal_noise, 3).reshape(dimensions[0],
                                                             dimensions[1],
                                                             dimensions[2],
                                                             1)
    temporal_noise = temporal_noise - temporal_noise_mean

    # Save the combination
    system_noise = spatial_noise + temporal_noise

    return system_noise