code: def _generate_noise_spatial(
      dimensions,
      mask=None,
      fwhm=4.0,
  ):
      """Generate code for Gaussian Random Fields.
  
      Adapted from code found here:
      http://andrewwalker.github.io/statefultransitions/post/gaussian-fields/
      with permission from the author:
      https://twitter.com/walkera101/status/785578499440377858. Original code
      comes from http://mathematica.stackexchange.com/questions/4829
      /efficiently-generating-n-d-gaussian-random-fields with a WTFPL (
      http://www.wtfpl.net).
  
      Parameters
      ----------
  
      dimensions : 3 length array, int
          What is the shape of the volume to be generated. This code
          compresesses the range if the x and y dimensions are not equivalent.
          This fixes this by upsampling and then downsampling the volume.
  
      template : 3d array, float
          A continuous (0 -> 1) volume describing the likelihood a voxel is in
          the brain. This can be used to contrast the brain and non brain.
  
      mask : 3 dimensional array, binary
          The masked brain, thresholded to distinguish brain and non-brain
  
      fwhm : float
          What is the full width half max of the gaussian fields being created.
          This is converted into a sigma which is used in this function.
          However, this conversion was found empirically by testing values of
          sigma and how it relates to fwhm values. The relationship that would be
          found in such a test depends on the size of the brain (bigger brains
          can have bigger fwhm).
          However, small errors shouldn't matter too much since the fwhm
          generated here can only be approximate anyway: firstly, although the
          distribution that is being drawn from is set to this value,
          this will manifest differently on every draw. Secondly, because of
          the masking and dimensions of the generated volume, this does not
          behave simply- wrapping effects matter (the outputs are
          closer to the input value if you have no mask).
          Use _calc_fwhm on this volume alone if you have concerns about the
          accuracy of the fwhm.
  
      Returns
      ----------
  
      noise_spatial : 3d array, float
          Generates the spatial noise volume for these parameters
  
      """
  
      # Check the input is correct
      if len(dimensions) == 4:
          logger.warning(
              "4 dimensions have been supplied, only using 3"
          )
          dimensions = dimensions[0:3]
  
      # If the dimensions are wrong then upsample now
      if (
          dimensions[0] != dimensions[1]
          or dimensions[1] != dimensions[2]
      ):
          max_dim = np.max(dimensions)
          new_dim = (max_dim, max_dim, max_dim)
      else:
          new_dim = dimensions
  
      def _logfunc(x, a, b, c):
          """Solve for y given x for log function.
  
          Parameters
          ----------
  
          x : float
              x value of log function
  
          a : float
              x shift of function
  
          b : float
              rate of change
  
          c : float
              y shift of function
  
          Returns
          ----------
  
          float
              y value of log function
          """
          return (np.log(x + a) / np.log(b)) + c
  
      def _fftIndgen(n):
          """# Specify the fft coefficents
  
          Parameters
          ----------
  
          n : int
              Dim size to estimate over
  
          Returns
          ----------
  
          array of ints
              fft indexes
          """
  
          # Pull out the ascending and descending indexes
          ascending = np.linspace(0, int(n / 2), int(n / 2 + 1))
          elements = int(
              np.ceil(n / 2 - 1)
          )  # Round up so that len(output)==n
          descending = np.linspace(-elements, -1, elements)
  
          return np.concatenate((ascending, descending))
  
      def _Pk2(idxs, sigma):
          """# Specify the amplitude given the fft coefficents
  
          Parameters
          ----------
  
          idxs : 3 by voxel array int
              fft indexes
  
          sigma : float
              spatial sigma
  
          Returns
          ----------
  
          amplitude : 3 by voxel array
              amplitude of the fft coefficients
          """
  
          # The first set of idxs ought to be zero so make the first value
          # zero to avoid a divide by zero error
          amp_start = np.array((0))
  
          # Compute the amplitude of the function for a series of indices
          amp_end = np.sqrt(
              np.sqrt(np.sum(idxs[:, 1:] ** 2, 0)) ** (-1 * sigma)
          )
          amplitude = np.append(amp_start, amp_end)
  
          # Return the output
          return amplitude
  
      # Convert from fwhm to sigma (relationship discovered empirical, only an
      #  approximation up to sigma = 0 -> 5 which corresponds to fwhm = 0 -> 8,
      # relies on an assumption of brain size).
      spatial_sigma = _logfunc(
          fwhm, -0.36778719, 2.10601011, 2.15439247
      )
  
      noise = np.fft.fftn(np.random.normal(size=new_dim))
  
      # Create a meshgrid of the object
      fft_vol = np.meshgrid(
          _fftIndgen(new_dim[0]),
          _fftIndgen(new_dim[1]),
          _fftIndgen(new_dim[2]),
      )
  
      # Reshape the data into a vector
      fft_vec = np.asarray(
          (
              fft_vol[0].flatten(),
              fft_vol[1].flatten(),
              fft_vol[2].flatten(),
          )
      )
  
      # Compute the amplitude for each element in the grid
      amp_vec = _Pk2(fft_vec, spatial_sigma)
  
      # Reshape to be a brain volume
      amplitude = amp_vec.reshape(new_dim)
  
      # The output
      noise_fft = (np.fft.ifftn(noise * amplitude)).real
  
      # Fix the dimensionality of the data (if necessary)
      noise_spatial = noise_fft[
          : dimensions[0], : dimensions[1], : dimensions[2]
      ]
  
      # Mask or not, then z score
      if mask is not None:
          # Mask the output
          noise_spatial *= mask
  
          # Z score the specific to the brain
          noise_spatial[mask > 0] = stats.zscore(
              noise_spatial[mask > 0]
          )
      else:
          # Take the grand mean/std and use for z scoring
          grand_mean = (noise_spatial).mean()
          grand_std = (noise_spatial).std()
  
          noise_spatial = (noise_spatial - grand_mean) / grand_std
  
      return noise_spatial
  
imports: import logging
  from itertools import product
  from statsmodels.tsa.arima.model import ARIMA
  import math
  import numpy
  from numpy.linalg import LinAlgError
  from pkg_resources import resource_stream
  from scipy import stats
  from scipy import signal
  import scipy.ndimage
  import copy
  from scipy import optimize
label_desc: Use image node_id 20 for calling a global function with example usage: _generate_noise_spatial(dimensions, mask, fwhm) and returns: noise_spatial, unknown, np, amplitude