Nothing
#' @title Conduct the cross superlet transform on a time series or signal
#'
#' @description
#' Compute the cross superlet transform using a complex Morlet wavelet based on
#' the approach of Moca et al. (2021) and the "analyze.coherency" function of the WaveletComp
#' package. The superlet transform increases time frequency resolution by
#' combining multiple wavelet orders at each frequency.
#'
#' @param data_1 First input data set as a matrix or data frame. The first column must
#' represent depth or time, and the second column the signal or proxy record.
#'
#' @param data_2 Second input data as a matrix or data frame. The first column must
#' represent depth or time, and the second column the signal or proxy record.
#'
#' @param upperPeriod Maximum period to be analysed. Controls the lowest
#' analysed frequency.
#'
#' @param lowerPeriod Minimum period to be analysed. Controls the highest
#' analysed frequency.
#'
#' @param Nf Number of frequencies used to construct the superlet spectrum.
#' Frequencies are logarithmically spaced between the limits defined by
#' \code{upperPeriod} and \code{lowerPeriod}.
#'
#' @param c1 Base number of cycles of the Morlet wavelet. Acts as the
#' fundamental wavelet width.
#'
#' @param o numeric vector of length two defining the minimum and
#' maximum superlet order. If NULL, all frequencies are analysed using
#' order one.
#'
#' @param mult Logical. If TRUE, the number of cycles increases
#' multiplicatively with superlet order. If FALSE, cycles increase
#' additively.
#'
#' @param order_scaling Character string defining how the number of wavelet
#' cycles varies with scale. One of
#' \code{"log2"}, \code{"linear"}, \code{"sqrt"}, \code{"quadratic"},
#' or \code{"power"}.
#'
#' @param order_alpha Numeric. Exponent used when \code{scaling = "power"}.
#' Values greater than one emphasize high frequency sharpening, whereas
#' values smaller than one emphasize low frequency sharpening.
#'
#' @param verbose Logical. If TRUE, print progress and interpolation
#' information.
#'
#' @return
#'A list with class \code{"analyze.Xsuperlet"} containing
#'Wave: complex wavelet coefficients
#'Power: time frequency power spectrum
#'dt: sampling interval after interpolation
#'Phase: instantaneous phase of the signal
#'dj: number of frequencies
#'Power.avg: average spectral power
#'Period: physical periods corresponding to frequencies
#'nc: number of columns in the input data
#'nr: number of frequency levels
#'axis.1: x axis values (time or depth)
#'axis.2: y axis values (log2 scaled periods)
#'c1: base number of wavelet cycles
#'o: numeric vector of length two defining the minimum and
#' maximum superlet order. If NULL, all frequencies are analysed using
#' order one.
#'x1: interpolated x values first data set
#'y1: interpolated signal values first data set
#'x2: interpolated x values second data set
#'y2: interpolated signal values second data set
#'
#' @author
#' The "analyze_Xsuperlet" that generates the input for the plotting function
#' is based on the matlab code in Moca et al. (2021) and the the "analyze.coherency" function of the 'WaveletComp' R package
#'
#' @references
#' Moca, V. V., Bârzan, H., Nagy-Dăbâcan, A., & Mureșan, R. C. (2021).
#' Time-frequency super-resolution with superlets.
#' Nature Communications, 12(1), 337.
#' \doi{10.1038/s41467-020-20539-9}
#'@examples
#' \donttest{
#'#Example 1. A cross superlet of two etp solutions with noise overprint
#'etp_1 <- astrochron::etp(
#' tmin = 0,
#' tmax = 300,
#' dt = 1,
#' eWt = 1.5,
#' oWt = 0.75,
#' pWt = 1,
#' esinw = TRUE,
#' standardize = TRUE,
#' genplot = FALSE,
#' verbose = FALSE
#')
#'
#'etp_2 <- astrochron::etp(
#' tmin = 0,
#' tmax = 300,
#' dt = 1,
#' eWt = 1,
#' oWt = 0.5,
#' pWt = 1.5,
#' esinw = TRUE,
#' standardize = TRUE,
#' genplot = FALSE,
#' verbose = FALSE
#')
#'
#'etp_1[, 2] <- etp_1[, 2] + colorednoise::colored_noise(
#' nrow(etp_1),
#' sd = sd(etp_1[, 2]) / 1.5,
#' mean = mean(etp_1[, 2]),
#' phi = 0.9
#')
#'etp_2[, 2] <- etp_2[, 2] + colorednoise::colored_noise(
#' nrow(etp_2),
#' sd = sd(etp_2[, 2]) / 1.5,
#' mean = mean(etp_2[, 2]),
#' phi = 0.9
#')
#'
#'Xetp <- analyze_Xsuperlet(
#' data_1 = etp_1,
#' data_2 = etp_2,
#' upperPeriod = 256,
#' lowerPeriod = 2,
#' Nf = 32,
#' c1 = 3,
#' o = c(1, 10),
#' mult = TRUE,
#' order_scaling = "log2",
#' order_alpha = 1,
#' verbose = FALSE
#')
#'}
#' @export
#' @importFrom stats sd
#' @importFrom stats median
#' @importFrom stats fft
#' @importFrom stats fft
#' @importFrom astrochron etp
analyze_Xsuperlet <- function(data_1 = NULL,
data_2 = NULL,
upperPeriod = 2,
lowerPeriod = 1024,
Nf = 128,
c1 = 3,
o = c(1, 10),
mult = TRUE,
order_scaling = "log2",
order_alpha = 1,
verbose = FALSE) {
data_1 <- data_1[order(data_1[, 1]), ]
data_2 <- data_2[order(data_2[, 1]), ]
# Determine overlapping interval
xmin <- max(min(data_1[, 1], na.rm = TRUE), min(data_2[, 1], na.rm = TRUE))
xmax <- min(max(data_1[, 1], na.rm = TRUE), max(data_2[, 1], na.rm = TRUE))
dx1 <- median(diff(data_1[, 1]))
dx2 <- median(diff(data_2[, 1]))
dx <- max(dx1, dx2) # conservative choice
common_grid <- seq(from = xmin, to = xmax, by = dx)
data_1_common <- data.frame(x = common_grid,
proxy = approx(data_1[, 1], data_1[, 2], xout = common_grid, rule = 1)$y)
data_2_common <- data.frame(x = common_grid,
proxy = approx(data_2[, 1], data_2[, 2], xout = common_grid, rule = 1)$y)
superlet_1 <- analyze_superlet(
data = data_1_common,
upperPeriod = upperPeriod,
lowerPeriod = lowerPeriod,
Nf = Nf,
c1 = c1,
o = o,
mult = mult,
verbose = verbose
)
superlet_2 <- analyze_superlet(
data = data_2_common,
upperPeriod = upperPeriod,
lowerPeriod = lowerPeriod,
Nf = Nf,
c1 = c1,
o = o,
mult = mult,
verbose = verbose
)
# CROSS-ANALYSIS CALCULATIONS
# Extract shared parameters from the Superlet output
dt <- superlet_1$dt
Scale <- superlet_1$Scale
nc <- superlet_1$nc
nr <- superlet_1$nr
# Raw Cross-Wavelet: Multiply complex coefficients and normalize by Scale
# This mirrors the logic: Wave.xy = (W1 * Conj(W2)) / Scale
Wave.xy <- (superlet_1$Wave * Conj(superlet_2$Wave)) / matrix(rep(Scale, nc), nrow = nr)
Power.xy <- Mod(Wave.xy)
Phase.xy <- Arg(Wave.xy)
output <- list(
Wave = t(Wave.xy),
Power = t(Power.xy),
Phase = t(Phase.xy),
dt = dt,
dj = 1 / Nf,
Power.avg = colMeans(t(Power.xy), na.rm = TRUE),
Scale = Scale,
Period = superlet_1$Period,
nc = nc,
nr = Nf,
axis.1 = superlet_1$axis.1,
axis.2 = superlet_1$axis.2,
c1 = c1,
o = o,
x1 = superlet_1$x,
y1 = superlet_1$y,
x2 = superlet_2$x,
y2 = superlet_2$y
)
class(output) <- "analyze.Xsuperlet"
return(output)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.