% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/baseline.R
\name{baseline_array}
\alias{baseline_array}
\alias{baseline_array.array}
\title{Calculate Contrasts of Arrays in Different Methods}
\usage{
baseline_array(x, along_dim, unit_dims = seq_along(dim(x))[-along_dim], ...)

\method{baseline_array}{array}(
  x,
  along_dim,
  unit_dims = seq_along(dim(x))[-along_dim],
  method = c("percentage", "sqrt_percentage", "decibel", "zscore", "sqrt_zscore",
    "db_zscore", "subtract_mean"),
  baseline_indexpoints = NULL,
  baseline_subarray = NULL,
  ...
)
}
\arguments{
\item{x}{array (tensor) to calculate contrast}

\item{along_dim}{integer range from 1 to the maximum dimension of \code{x}.
baseline along this dimension, this is usually the time dimension.}

\item{unit_dims}{integer vector, baseline unit: see Details.}

\item{...}{passed to other methods}

\item{method}{character, baseline method; one of \code{"percentage"},
\code{"sqrt_percentage"}, \code{"decibel"}, \code{"zscore"},
\code{"sqrt_zscore"}, \code{"db_zscore"}, or \code{"subtract_mean"}.
See Details.}

\item{baseline_indexpoints}{integer vector, which index points are counted
into baseline window? Each index ranges from 1 to \code{dim(x)[[along_dim]]}.
See Details.}

\item{baseline_subarray}{sub-arrays that should be used to calculate
baseline; default is \code{NULL} (automatically determined by
\code{baseline_indexpoints}).}
}
\value{
Contrast array with the same dimension as \code{x}.
}
\description{
Provides seven methods to baseline an array and calculate
contrast.
}
\details{
Consider a scenario where we want to baseline a bunch of signals recorded
from different locations. For each location, we record \code{n} sessions.
For each session, the signal is further decomposed into frequency-time
domain. In this case, we have the input \code{x} in the following form:
\deqn{session \times frequency \times time \times location}
Now we want to calibrate signals for each session, frequency and location
using the first 100 time points as baseline points, then the code will be
\code{baseline_array(x, along_dim=3, baseline_window=1:100, unit_dims=c(1,2,4))}
\code{along_dim=3} is dimension of time, in this case, it's the
third dimension of \code{x}. \code{baseline_indexpoints=1:100}, meaning
the first 100 time points are used to calculate baseline.
\code{unit_dims} defines the unit signal. Its value \code{c(1,2,4)}
means the unit signal is per session (first dimension), per frequency
(second) and per location (fourth).

In some other cases, we might want to calculate baseline across frequencies
then the unit signal is \eqn{frequency x time}, i.e. signals that share the
same session and location also share the same baseline. In this case,
we assign \code{unit_dims=c(1,4)}.

There are seven baseline methods. They fit for different types of data.
Denote \eqn{z} is a unit signal and \eqn{z_0} is its baseline slice. Then
these baseline methods are:

\describe{
\item{\code{"percentage"}}{
\deqn{
  \frac{z - \bar{z_{0}}}{\bar{z_{0}}} \times 100\%
}{
  (z / mean(z_0) - 1) x 100\%
}
}
\item{\code{"sqrt_percentage"}}{
\deqn{
  \frac{\sqrt{z} - \bar{\sqrt{z_{0}}}}{\bar{\sqrt{z_{0}}}} \times 100\%
}{
  (sqrt(z) / mean(sqrt(z_0)) - 1) x 100\%
}
}
\item{\code{"decibel"}}{
\deqn{
  10 \times ( \log_{10}(z) - \bar{\log_{10}(z_{0})} )
}{
  10 * ( log10(z) - mean( log10(z_0) ) )
}
}
\item{\code{"zscore"}}{
\deqn{
  \frac{z-\bar{z_{0}}}{sd(z_{0})}
}{
  (z - mean( z_0 )) / sd( z_0 )
}
}
\item{\code{"sqrt_zscore"}}{
\deqn{
  \frac{\sqrt{z}-\bar{\sqrt{z_{0}}}}{sd(\sqrt{z_{0}})}
}{
  (sqrt(z) - mean( sqrt(z_0) )) / sd( sqrt(z_0) )
}
}
\item{\code{"db_zscore"}}{
Z-score applied in the decibel (10log10) domain:
\deqn{
  \frac{10\log_{10}(z) - \bar{10\log_{10}(z_{0})}}{sd(10\log_{10}(z_{0}))}
}{
  ( log10(z) - mean( log10(z_0) ) ) / sd( log10(z_0) )
}
}
\item{\code{"subtract_mean"}}{
Simple mean subtraction with no scaling:
\deqn{
  z - \bar{z_{0}}
}{
  z - mean(z_0)
}
}


}
}
\examples{

# Set ncores = 2 to comply to CRAN policy. Please don't run this line
ravetools_threads(n_threads = 2L)


library(ravetools)
set.seed(1)

# Generate sample data
dims = c(10,20,30,2)
x = array(rnorm(prod(dims))^2, dims)

# Set baseline window to be arbitrary 10 timepoints
baseline_window = sample(30, 10)

# ----- baseline percentage change ------

# Using base functions
re1 <- aperm(apply(x, c(1,2,4), function(y) {
  m <- mean(y[baseline_window])
  (y/m - 1) * 100
}), c(2,3,1,4))

# Using ravetools
re2 <- baseline_array(x, 3, c(1,2,4),
                      baseline_indexpoints = baseline_window,
                      method = 'percentage')

# Check different, should be very tiny (double precisions)
range(re2 - re1)

\donttest{
# Check speed for large dataset, might take a while to profile

ravetools_threads(n_threads = -1)

dims <- c(200,20,300,2)
x <- array(rnorm(prod(dims))^2, dims)
# Set baseline window to be arbitrary 10 timepoints
baseline_window <- seq_len(100)
f1 <- function() {
  aperm(apply(x, c(1,2,4), function(y) {
    m <- mean(y[baseline_window])
    (y/m - 1) * 100
  }), c(2,3,1,4))
}
f2 <- function() {
  # equivalent as bl = x[,,baseline_window, ]
  #
  baseline_array(x, along_dim = 3,
                 baseline_indexpoints = baseline_window,
                 unit_dims = c(1,2,4), method = 'percentage')
}
range(f1() - f2())
microbenchmark::microbenchmark(f1(), f2(), times = 10L)

}



}
