Make a periodogram or amplitude-spectrum of a time series that has a
  non-constant sampling rate. The spectra output by this program are
  'one-sided', so that they represent the half-amplitude or power
  associated with a frequency, and they would require a factor of 2 to
  account for both the the right- and left-traveling frequency solutions
  of the Fourier transform (see below 'OUTPUT' and 'NOTE').

  Of particular interest is the application of this functionality to
  resting state time series that may have been censored.  The theory behind
  the mathematics and algorithms of this is due to separate groups, mainly
  in the realm of astrophysical applications: Vaníček (1969, 1971),
  Lomb (1976), Scargle (1982), and Press & Rybicki (1989). Shoutout to them.

  This particular implementation is due to Press & Rybicki (1989), by
  essentially translating their published Fortran implementation into C,
  while using GSL for the FFT, instead of NR's realft(), and making
  several adjustments based on that.

  The Lomb-Scargle adaption was done with fairly minimal changes here by
  PA Taylor (v1.4, June, 2016).

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

  + USAGE:
      Input a 4D volumetric time series (BRIK/HEAD or NIFTI data set)
      as well as an optional 1D file of 0s and 1s that defines which points
      to censor out (i.e., each 0 represents a point/volume to censor out);
      if no 1D file is input, the program will check for volumes that are
      uniformly zero and consider those to be censored.

      The output is a LS periodogram, describing spectral magnitudes
      up to some 'maximum frequency'-- the default max here is what
      the Nyquist frequency of the time series *would have been* without
      any censoring.  (Interestingly, this analysis can actually be
      legitimately applied in cases to estimate frequency content >Nyquist.

      The frequency spectrum will be in the range [df, f_N], where:
        df = 1/T, and T is the total duration of the uncensored time series;
        f_N = 1/dt, and dt is the sampling time (i.e., TR);
        and the interval of frequencies is also df.
      These ranges and step sizes should be *independent* of the censoring
      which is a nice property of the Lomb-Scargle-iness.

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    1) PREFIX_time.1D    :a 1D file of the sampled time points (in units of
                          seconds) of the analyzed (and possibly censored)
                          data set.
    2) PREFIX_freq.1D    :a 1D file of the frequency sample points (in units
                          of 1/seconds) of the output periodogram/spectrum
                          data set.
    3) PREFIX_amp+orig   :volumetric data set containing a LS-derived
             or           amplitude spectrum (by default, named 'amp') or a
       PREFIX_pow+orig    power spectrum (see '-out_pow_spec', named 'pow')
                          one per voxel.
                          Please note that the output amplitude and power
                          spectra are 'one-sided', to represent the
                          *half* amplitude or power of a given frequency
                          (see the following note).

  + A NOTE ABOUT Fourier+Parseval matters (please forgive the awkward
      In the formulation used here, for a time series x[n] of length N,
      the periodogram value S[k] is related to the amplitude value |X[k]|:
       (1)     S[k] = (|X[k]|)**2,
      for each k-th harmonic.

      Parseval's theorem relates time fluctuations to spectral amplitudes,
      stating that (for real time series with zero mean):
       (2)     sum_n{ x[n]**2 } = (1/N) * sum_k{ |X[k]|**2 },
                                = (1/N) * sum_k{ S[k] },
      where n=0,1,..,N-1 and k=0,1,..,N-1 (NB: A[0]=0, for zero mean
      series). The LHS is essentially the variance of the time series
      (times N-1).  The above is derived from Fourier transform maths, and
      the Lomb-Scargle spectra are approximations to Fourier, so the above
      can be expected to approximately hold, if all goes well.

      Another Fourier-related result is that for real, discrete time series,
      the spectral amplitudes/power values are symmetric and periodic in N.
      Therefore, |X[k]| = |X[-k]| = |X[N-k-1]| (in zero-base array
      the distinction between positive- and negative-indexed frequencies
      can be thought of as signifying right- and left-traveling waves, which
      both contribute to the total power of a specific frequency.
      The upshot is that one could write the Parseval formula as:
       (3)     sum_n{ x[n]**2 } = (2/N) * sum_l{ |X[l]|**2 },
                                = (2/N) * sum_l{ S[l] },
      where n=0,1,..,N-1 and l=0,1,..,(N/2)-1 (note the factor of 2 now
      appearing on the RHS relations). These symmetries/considerations
      are the reason why ~N/2 frequency values are output here (we assume
      that only real-valued time series are input), without any loss of

      Additionally, with a view toward expressing the overall amplitude
      or power of a given frequency, which many people might want to use to
      estimate spectral 'functional connectivity' parameters such as ALFF,
      fALFF, RSFA, etc. (using, for example, 3dAmptoRSFC), we therefore
      note that the *total* amplitude or power of a given frequency would
            A[k] = 2*|X[k]|
            P[k] = 2*S[k] = 2*|X[k]|**2 = 0.5*A[k]**2
      instead of just that of the left/right traveling part. These types of
      quantities (A and P) are also referred to as 'two-sided' spectra. The
      resulting Parseval relation could then be written:
       (4)     sum_n{ x[n]**2 } = (1/(2N)) * sum_l{ A[l]**2 },
                                = (1/N) * sum_l{ P[l] },
      where n=0,1,..,N-1 and l=0,1,..,(N/2)-1. Somehow, it just seems easier
      to output the one-sided values, X and S, so that the Parsevalian
      summation rules look more similar.

      With all of that in mind, the 3dLombScargle results are output as
      follows. For amplitudes, the following approx. Parsevellian relation
      should hold between the 'holey' time series x[m] of M points and
      the frequency series Y[l] of L~M/2 points (where {|Y[l]|} approaches
      the Fourier amplitudes {|X[l]|} as the number of censored points
      decreases and M->N):
       (5)     sum_m{ x[m]**2 } = (1/L) * sum_l{ Y[l]**2 },
      where m=0,1,..,M-1 and l=0,1,..,L-1. For the power spectrum T[l]
      of L~M/2 values, then:
       (6)     sum_m{ x[m]**2 } = (1/L) * sum_l{ T[l] }
      for the same ranges of summations.

      So, please consider that when using the outputs of here. 3dAmpToRSFC
      is prepared for this when calculating spectral parameters (from

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

  + COMMAND:  3dLombScargle -prefix PREFIX -inset FILE \
                  {-censor_1D C1D} {-censor_str CSTR} \
                  {-mask MASK} {-out_pow_spec}  \
                  {-nyq_mult N2}  {-nifti}

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

  -prefix PREFIX   :output prefix name for data volume, time point 1D file
                    and frequency 1D file.
  -inset FILE      :time series of volumes, a 4D volumetric data set.

  -censor_1D C1D   :single row or column of 1s (keep) and 0s (censored)
                    describing which volumes of FILE are kept in the
                    sampling and which are censored out, respectively. The
                    length of the list of numbers must be of the
                    same length as the number of volumes in FILE.
                    If not entered, then the program will look for subbricks
                    of all-zeros and assume those are censored out.
  -censor_str CSTR :AFNI-style selector string of volumes to *keep* in
                    the analysis.  Such as:
                    Why we refer to it as a 'censor string' when it is
                    really the list of volumes to keep... well, it made
                    sense at the time.  Future historians can duel with
                    ink about it.

  -mask MASK       :optional, mask of volume to analyze; additionally, any
                    voxel with uniformly zero values across time will
                    produce a zero-spectrum.

  -out_pow_spec    :switch to output the amplitude spectrum of the freqs
                    instead of the periodogram.  In the formulation used
                    here, for a time series of length N, the power spectral
                    value S is related to the amplitude value X as:
                    S = (X)**2. (Without this opt, default output is
                    amplitude spectrum.)

  -nyq_mult N2     :L-S periodograms can include frequencies above what
                    would typically be considered Nyquist (here defined
                     f_N = 0.5*(number of samples)/(total time interval)
                    By default, the maximum frequency will be what
                    f_N *would* have been if no censoring of points had
                    occurred. (This makes it easier to compare L-S spectra
                    across a group with the same scan protocol, even if
                    there are slight differences in censoring, per subject.)
                    Acceptable values are >0. (For those reading the
                    algorithm papers, this sets the 'hifac' parameter.)
                    If you don't have a good reason for changing this,
                    dooon't change it!
  -nifti           :switch to output *.nii.gz volume file
                    (default format is BRIK/HEAD).

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

        3dLombScargle -prefix LSout -inset TimeSeries.nii.gz \
             -mask mask.nii.gz -censor_1D censor_list.txt

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *