code: def p_from_null(
      observed, distribution, side="two-sided", exact=False, axis=None
  ):
      """Compute p-value from null distribution
  
      Returns the p-value for an observed test statistic given a null
      distribution. Performs either a 'two-sided' (i.e., two-tailed)
      test (default) or a one-sided (i.e., one-tailed) test for either the
      'left' or 'right' side. For an exact test (exact=True), does not adjust
      for the observed test statistic; otherwise, adjusts for observed
      test statistic (prevents p-values of zero). If a multidimensional
      distribution is provided, use axis argument to specify which axis indexes
      resampling iterations.
  
      The implementation is based on the work in [PhipsonSmyth2010]_.
  
      .. [PhipsonSmyth2010] "Permutation p-values should never be zero:
         calculating exact p-values when permutations are randomly drawn.",
         B. Phipson, G. K., Smyth, 2010, Statistical Applications in Genetics
         and Molecular Biology, 9, 1544-6115.
         https://doi.org/10.2202/1544-6115.1585
  
      Parameters
      ----------
      observed : float
          Observed test statistic
  
      distribution : ndarray
          Null distribution of test statistic
  
      side : str, default: 'two-sided'
          Perform one-sided ('left' or 'right') or 'two-sided' test
  
      axis: None or int, default: None
          Axis indicating resampling iterations in input distribution
  
      Returns
      -------
      p : float
          p-value for observed test statistic based on null distribution
      """
  
      if side not in ("two-sided", "left", "right"):
          raise ValueError(
              "The value for 'side' must be either "
              "'two-sided', 'left', or 'right', got {0}".format(side)
          )
  
      n_samples = len(distribution)
      logger.info(
          "Assuming {0} resampling iterations".format(n_samples)
      )
  
      if side == "two-sided":
          # Numerator for two-sided test
          numerator = np.sum(
              np.abs(distribution) >= np.abs(observed), axis=axis
          )
      elif side == "left":
          # Numerator for one-sided test in left tail
          numerator = np.sum(distribution <= observed, axis=axis)
      elif side == "right":
          # Numerator for one-sided test in right tail
          numerator = np.sum(distribution >= observed, axis=axis)
  
      # If exact test all possible permutations and do not adjust
      if exact:
          p = numerator / n_samples
  
      # If not exact test, adjust number of samples to account for
      # observed statistic; prevents p-value from being zero
      else:
          p = (numerator + 1) / (n_samples + 1)
  
      return p
  
imports: import numpy
  import re
  import warnings
  import os.path
  import psutil
  from .fmrisim import generate_stimfunction, _double_gamma_hrf, convolve_hrf
  from scipy.fftpack import fft, ifft
  import logging
label_desc: Use image node_id 13 for calling a global function with example usage: p_from_null(observed, distribution, side, exact, axis) and returns: p