#' Read a SAC binary file
#' @description
#' Loads SAC (Seismic Analysis Code) data files [1], stored as either
#' ASCII or binary format.
#'
#' From [2]:
#' \emph{
#' [SAC] files contain a fixed length header section followed by one or
#' two data sections. The header contains floating point, integer, logical,
#' and character fields. Evenly spaced data files have only one data section
#' which contains the dependent variable. Unevenly spaced data and spectral
#' data files contain two data sections. For unevenly spaced data, the first
#' data section contains the dependent variable and the second contains the
#' independent variable. For spectral files the first component is either
#' the amplitude or the real component and the second component is either
#' the phase or imaginary component.
#' }
#'
#' @details
#' The ASCII reader (\code{\link{.sacreader.asc}}) is simply a series
#' of \code{\link{read.table}} calls,
#' and the binary reader (\code{\link{.sacreader.bin}}) uses
#' \code{\link{readBin}} with the specified endianness.
#'
#' \subsection{Utility functions}{
#' \code{\link{sync}}:
#' From documentation in the last available version of \code{Rsac}:
#' \emph{
#' Synchronizes the reference times of all files in a vector of SAC files.
#' [...]
#' This is useful if you are sending each file to a different plot but
#' want the relative time to be consistent between the different plots.
#' }
#'
#' \code{\link{sacunits}}:
#' From documentation in the last available version of \code{Rsac}:
#' \emph{
#' Looks up the units of the [amplitudes in the] SAC record. The units in many seismic
#' headers are notoriously unreliable, so care should be taken to
#' find an independent source to confirm the units.
#' }
#'
#' \code{\link{fstart}}:
#' From documentation in the last available version of \code{Rsac}:
#' \emph{
#' Calculates the starting time [of the SAC data].
#' }
#' }
#' @name sacfiles
#' @aliases sacfile sac read_sac
#' @author A.J. Barbour modified code from the (now defunct)
#' package \code{Rsac}, written originally by E.M. Thompson.
#'
#' @param files character; the file(s) to read in
#' @param is.binary logical; are the sac files in \code{files} binary or ASCII?
#' @param endianness character; specify the endianness of \code{file}.
#' \code{'auto'} uses the platform value, or \code{'little'} and \code{'big'}
#' can be used to force a specific structure.
#' @param ... additional parameters;
#' For \code{\link{read.sac}}: additional objects to the sac reader;
#' for \code{\link{c.saclist}}: the objects to concatenate
#' @param fi character; a single filename
#' @param na.value the \code{NA} representation
#' @param amp.as.ts logical; should the amplitudes be converted to a \code{'ts'} object?
#' @param x an object to operate on.
#' @param object an object to operate on.
#' @param recursive logical; From \code{\link{c}}:\emph{
#' If \code{recursive = TRUE}, the function recursively descends
#' through lists (and pairlists) combining all their elements into a vector.
#' }
#' @param ncol numeric; the number of columns in the plot \code{\link{layout}}
#' @param relative logical; should the start times be relative to
#' the minimum of the group?
#' @param trim numeric; the fraction of data to trim from the start and end
#' of the amplitude record for the statistical summary. Can be a two-length
#' vector, but must be within [0,0.5].
#' @param rel.time POSIXct; report the number of seconds relative to this
#' @param stat.annotate logical; should statistical annotations be shown?
#' @param apply.calib logical; should the calibration factor in the sac header be applied?
#'
#' @return A list of lists, with class \code{'saclist'}, where each
#' item corresponds to the contents of each entry in
#' \code{files}, each with class \code{'sac'}.
#'
#' @references [1] \url{http://www.iris.edu/software/sac/}
#' @references [2] \url{http://www.iris.edu/files/sac-manual/}
#'
#' @seealso \code{\link{irisws-package}}
#'
#' @family SAC
#'
#' @examples
#' \dontrun{
#' ##
#' ## Methods for .sac data
#' ##
#' #
#' # Load pore pressure at B084 during the El Majoy Cucapah earthquake:
#' #
#' sacfi <- system.file("sac/elmayorB084_LDD.sac", package="irisws")
#' # this is a little-endian sac file, so
#' # must specify (your system may be 'big'!)
#' x1 <- read.sac(sacfi, is.binary=TRUE, endianness="little")
#' # returns an object of class 'saclist'
#' plot(x1)
#' ##
#' ## SAC ASCII reader
#' ##
#' sacascfi <- system.file("sac/elmayorB084_LDD.txt", package="irisws")
#' x2 <- read.sac(sacascfi, is.binary=FALSE)
#' plot(x2)
#' all.equal(x1[1]$amp, x2[1]$amp) # they are equal, as expected
#' #
#' # Can also load a series of files:
#' #
#' sacfis <- rep(sacfi, 3)
#' x3 <- read.sac(sacfis, is.binary=TRUE, endianness="little")
#' plot(x3) # now there are three frames in the plot (all the same data, obviously)
#' #
#' # Utilities
#' #
#' c(x1)
#' sacunits(x1)
#'
#' }
NULL
#' @rdname sacfiles
#' @export
read.sac <- function(files, is.binary, endianness=c("auto","little","big"), ...){
sacfiles <- as.character(files)
nsacfi <- length(sacfiles)
sacdat <- vector(mode="list", length=nsacfi)
#
# try and find out
#scan("iriswsQ.PB.B084.--.LDD.2013-10-01T00:00:00.100s.sac", numeric(), n=1)
# NA for sac, 1 for txt
if (is.binary){
endian <- match.arg(endianness)
if (endian=="auto"){
endian <- .Platform[["endian"]]
}
SACR <- function(Fi, ...){.sacreader.bin(Fi, endian, ...)}
} else {
SACR <- function(Fi, ...){.sacreader.asc(Fi, ...)}
}
#
for (fi in seq_len(nsacfi)){
sfi <- sacfiles[fi]
sacdat[[fi]] <- SACR(sfi, ...)
}
class(sacdat) <- "saclist"
return(sacdat)
}
#' @rdname sacfiles
#' @export
.sacreader.asc <- function(fi, na.value=c("-12345","-12345.00"), amp.as.ts=TRUE){
#
HFUN <- function(H, i0, j0){
H[i0,j0]
}
#H 1 -- 5-col
h1 <- read.table(fi, skip=0, nrows=14, na.strings=na.value)
dt <- HFUN(h1, 1, 1)
depmin <- HFUN(h1, 1, 2)
depmax <- HFUN(h1, 1, 3)
scale <- HFUN(h1, 1, 4)
odelta <- HFUN(h1, 1, 5)
b <- HFUN(h1, 2, 1)
e <- HFUN(h1, 2, 2)
o <- HFUN(h1, 2, 3)
a <- HFUN(h1, 2, 4)
f <- HFUN(h1, 5, 1)
stla <- HFUN(h1, 7, 2)
stlo <- HFUN(h1, 7, 3)
stel <- HFUN(h1, 7, 4)
stdp <- HFUN(h1, 7, 5)
evla <- HFUN(h1, 8, 1)
evlo <- HFUN(h1, 8, 2)
evel <- HFUN(h1, 8, 3)
evdp <- HFUN(h1, 8, 4)
mag <- HFUN(h1, 8, 5)
dist <- HFUN(h1, 11, 1)
az <- HFUN(h1, 11, 2)
baz <- HFUN(h1, 11, 3)
gcarc <- HFUN(h1, 11, 4)
cmpaz <- HFUN(h1, 12, 3)
cmpinc <- HFUN(h1, 12, 4)
# H 2
#H 2 -- 5-col
h2 <- read.table(fi, skip=14, nrows=8, na.strings=na.value)
nzyear <- HFUN(h2, 1, 1)
nzjday <- HFUN(h2, 1, 2)
nzhour <- HFUN(h2, 1, 3)
nzmin <- HFUN(h2, 1, 4)
nzsec <- HFUN(h2, 1, 5)
nzmsec <- HFUN(h2, 2, 1)
# 2,2 ?
norid <- HFUN(h2, 2, 3)
nevid <- HFUN(h2, 2, 4)
N <- HFUN(h2, 2, 5)
# 3: is empty (?)
# 4,1 (?)
idep <- HFUN(h2, 4, 2)
iztype <- HFUN(h2, 4, 3)
#
leven <- HFUN(h2, 8, 1) #?
lpspol <- HFUN(h2, 8, 2) #?
#
#H 3 -- 2-col
h3 <- read.table(fi, skip=22, nrows=1, na.strings=na.value)
#
kstnm <- HFUN(h3, 1, 1)
kevnm <- HFUN(h3, 1, 2)
#H 3 -- 3-col
h4 <- read.table(fi, skip=23, nrows=7, na.strings=na.value)
#
khole <- HFUN(h4, 1, 1) #HFUN(h4, 25, 32, na.value)
ko <- HFUN(h4, 6, 1) # ? #HFUN(h4, 33, 40, na.value)
ka <- HFUN(h4, 6, 2) # ? #HFUN(h4, 41, 48, na.value)
kcmpnm <- HFUN(h4, 6, 3) #HFUN(h4, 161, 168, na.value)
knetwork <- HFUN(h4, 7, 1) #HFUN(h4, 169, 176, na.value)
kinst <- HFUN(h4, 7, 3) #HFUN(h4, 185, 192, na.value)
#
#H 4 -- 5-col - data
amp <- as.vector(as.matrix(read.table(fi, skip=30, na.strings=na.value)))
if (amp.as.ts){
amp <- ts(data=amp, deltat=as.numeric(dt))
}
#
contents <- list(amp = amp, dt = dt,
depmin = depmin, depmax = depmax,
scale = scale, odelta = odelta,
b = b, e = e, o = o, a = a, f = f,
stla = stla, stlo = stlo, stel = stel, stdp = stdp,
evla = evla, evlo = evlo, evel = evel, evdp = evdp,
mag = mag, dist = dist, az = az, baz = baz, gcarc = gcarc,
cmpaz = cmpaz, cmpinc = cmpinc,
nzyear = nzyear, nzjday = nzjday, nzhour = nzhour,
nzmin = nzmin, nzsec = nzsec,
nzmsec = nzmsec, norid = norid,
nevid = nevid, N = N,
units = idep,
iztype = iztype,
leven = leven, lpspol = lpspol,
sta = kstnm, kevnm = kevnm, khole = khole,
ko = ko, ka = ka,
comp = kcmpnm, knetwork = knetwork, kinst = kinst)
attr(contents, "sacfile") <- fi
attr(contents, "endianness") <- "NA--ASCII"
class(contents) <- "sac"
return(contents)
}
#' @rdname sacfiles
#' @export
.sacreader.bin <- function(fi, endianness=c("little","big"), na.value=-12345, amp.as.ts=TRUE){
endi <- match.arg(endianness)
# Open the file for reading
zz <- file(fi, "rb")
#
binsize <- 4L
##
## Read in the header information.
h1 <- try(readBin(con = zz, what = numeric(), n = 70, size = binsize, endian = endi))
dim(h1) <- c(5, 14)
h1 <- aperm(h1) # array transpose
# NA values:
h1[h1 == na.value] <- NA
##
##
h2 <- try(readBin(con = zz, what = integer(), n = 35, size = binsize, endian = endi))
dim(h2) <- c(5, 7)
h2 <- aperm(h2)
# NA values:
h2[h2 == na.value] <- NA
##
##
h3 <- try(readBin(con = zz, what = logical(), n = 5, size = binsize, endian = endi))
##
##
h4 <- try(readBin(con = zz, what = character(), n = 1, size = binsize, endian = endi))
#
# Define header proocessing function:
HFUN <- function(H, i0, i1){
H[i0, i1]
}
# and get variables...
# H1
dt <- HFUN(h1, 1, 1)
depmin <- HFUN(h1, 1, 2)
depmax <- HFUN(h1, 1, 3)
scale <- HFUN(h1, 1, 4)
odelta <- HFUN(h1, 1, 5)
b <- HFUN(h1, 2, 1)
e <- HFUN(h1, 2, 2)
o <- HFUN(h1, 2, 3)
a <- HFUN(h1, 2, 4)
f <- HFUN(h1, 5, 1)
stla <- HFUN(h1, 7, 2)
stlo <- HFUN(h1, 7, 3)
stel <- HFUN(h1, 7, 4)
stdp <- HFUN(h1, 7, 5)
evla <- HFUN(h1, 8, 1)
evlo <- HFUN(h1, 8, 2)
evel <- HFUN(h1, 8, 3)
evdp <- HFUN(h1, 8, 4)
mag <- HFUN(h1, 8, 5)
dist <- HFUN(h1, 11, 1)
az <- HFUN(h1, 11, 2)
baz <- HFUN(h1, 11, 3)
gcarc <- HFUN(h1, 11, 4)
cmpaz <- HFUN(h1, 12, 3)
cmpinc <- HFUN(h1, 12, 4)
# H 2
nzyear <- HFUN(h2, 1, 1)
nzjday <- HFUN(h2, 1, 2)
nzhour <- HFUN(h2, 1, 3)
nzmin <- HFUN(h2, 1, 4)
nzsec <- HFUN(h2, 1, 5)
nzmsec <- HFUN(h2, 2, 1)
norid <- HFUN(h2, 2, 3)
nevid <- HFUN(h2, 2, 4)
N <- HFUN(h2, 2, 5)
idep <- HFUN(h2, 4, 2)
iztype <- HFUN(h2, 4, 3)
# H 3
HFUN3 <- function(H, i0){
H[i0]
}
leven <- HFUN3(h3, 1)
lpspol <- HFUN3(h3, 2)
# H 4
HFUN4 <- function(HH, i0, i1, na.val){
nav <- as.character(na.val)
replacement <- paste(rep(" ", nchar(nav)),collapse="")
#|-12345|
#| |
x <- substr(HH, i0, i1)
sub(nav, replacement, x)
}
kstnm <- HFUN4(h4, 1, 8, na.value)
kevnm <- HFUN4(h4, 9, 24, na.value)
khole <- HFUN4(h4, 25, 32, na.value)
ko <- HFUN4(h4, 33, 40, na.value)
ka <- HFUN4(h4, 41, 48, na.value)
kcmpnm <- HFUN4(h4, 161, 168, na.value)
knetwork <- HFUN4(h4, 169, 176, na.value)
kinst <- HFUN4(h4, 185, 192, na.value)
#
# Get the amplitudes...
try(seek(con=zz, where=632))
try(x <- readBin(con=zz, what=numeric(), n=N, size=binsize, endian=endi))
#
close(zz)
#
# load up the final product
if (amp.as.ts){
x <- ts(data=x, deltat=dt)
}
contents <- list(amp = x, dt = dt,
depmin = depmin, depmax = depmax,
scale = scale, odelta = odelta,
b = b, e = e, o = o, a = a, f = f,
stla = stla, stlo = stlo, stel = stel, stdp = stdp,
evla = evla, evlo = evlo, evel = evel, evdp = evdp,
mag = mag, dist = dist, az = az, baz = baz, gcarc = gcarc,
cmpaz = cmpaz, cmpinc = cmpinc,
nzyear = nzyear, nzjday = nzjday, nzhour = nzhour,
nzmin = nzmin, nzsec = nzsec,
nzmsec = nzmsec, norid = norid,
nevid = nevid, N = N,
units = idep,
iztype = iztype,
leven = leven, lpspol = lpspol,
sta = kstnm, kevnm = kevnm, khole = khole,
ko = ko, ka = ka,
comp = kcmpnm, knetwork = knetwork, kinst = kinst)
attr(contents, "sacfile") <- fi
attr(contents, "endianness") <- endi
class(contents) <- "sac"
return(contents)
} # end READER
# Need to define indexing for Rsac so that it retains the rsac
# class to plotting will work correctly:
# @rdname sacfiles
# @param i indices specifying elements to extract or replace.
# @export
#"[.saclist" <- function(x, i){
# x <- unclass(x)
# x <- x[i]
# class(x) <- "sac"
# return(x)
#}
#' @rdname sacfiles
#' @export
c.saclist <- function(..., recursive = FALSE){
x <- base::c(unlist(unclass(list(...)), recursive = recursive))
class(x) <- "sac"
return(x)
}
#' @rdname sacfiles
#' @export
print.sac <- function(x, ...){
print.default(x, ...)
}
#' @rdname sacfiles
#' @export
print.saclist <- function(x, ...){
xs <- summary(unclass(x))
fis <- sapply(x, function(n) attr(n, "sacfile"))
message("++++\n++++\tsaclist composition:\n++++")
print(xs <- cbind(Sources=fis, xs))
return(invisible(xs))
}
#' @rdname sacfiles
#' @export
summary.saclist <- function(object, ...){
xs <- summaryStats(object, ...)
class(xs) <- 'summary.saclist'
return(xs)
}
#' @rdname sacfiles
#' @export
print.summary.saclist <- function(x, ...){
message("++++\n++++\tsaclist content summary:\n++++")
print(xs <- unclass(x))
return(invisible(xs))
}
#' @rdname sacfiles
#' @export
str.saclist <- function(object, ...){
invisible(sapply(object, str))
}
#' @rdname sacfiles
#' @export
plot.saclist <- function(x, ncol=1, stat.annotate=TRUE, trim = 0,
rel.time = NULL, apply.calib=TRUE, ...){
uts <- sacunits(x)
uts[uts == "Unknown"] <- ".raw counts."
#
tst <- sapply(x, fstart)
tst <- tst - min(tst)
#
nsacs <- length(x)
sacseq <- seq_len(nsacs)
op <- par(no.readonly = TRUE)
par(mar=c(2.5, 4.1, 1.4, 1.1), #5.1 4.1 4.1 2.1
oma=c(2.5, 0.5, 1.4, 0.5), #0 0 0 0
mgp=c(2.1, 0.7, 0)) # 3 1 0
on.exit(par(op))
lo <- layout(matrix(sacseq, ncol=ncol)) #, sacseq)
layout.show(lo)
X <- unclass(x)
for (n in sacseq){
fi <- attr(X[[n]],"sacfile")
ss <- summaryStats(X[[n]], trim=trim, rel.time=rel.time)
amp <- X[[n]]$amp
delt <- X[[n]]$dt
#print(c("SSRS",ss$relsec))
amp <- ts(amp, deltat=delt, start=ss$start.relsec) #tst[n])
#
ylab <- uts[n]
#annot1 <- c(ss$amp.MAD, ss$amp.SD)
annot2 <- c(ss$amp.hinge.lower, ss$amp.median, ss$amp.hinge.upper)
annot3 <- c(ss$amp.maximum, ss$amp.minimum)
if (apply.calib){
calib <- sum(c(ss$amp.calib.factor * 1., 0), na.rm=TRUE)
if (calib > 0){
#annot1 <- annot1 / calib
annot2 <- annot2 / calib
annot3 <- annot3 / calib
amp <- amp / calib
ylab <- paste(ylab, '[scaled]')
} else {
warning("could not find calibration factor")
}
}
#
x <- time(amp)
plot.default(x, as.vector(amp),
type="l",
xlab="",
ylab=ylab,
#col=NA,
...)
# statistical annotations
if (stat.annotate){
gcol <- "red"
#print(c(annot1,annot2,annot3))
#abline(h=annot1, lty=3, col=gcol)
gcol <- "grey50"
abline(h=annot2, lty=2, lwd=1.2, col=gcol)
gcol <- "red"
abline(h=annot3, lty=1, col=gcol)
points(c(ss$relsec.max, ss$relsec.min), annot3, col="blue")
}
#lines.default(x, as.vector(amp))
mtext(fi, cex=0.7)
sta <- X[[n]]$sta
mtext(sta,
side=3, cex=0.8, font=2, adj=0.01, line=-1.5)
timelbl <- with(ss,
strftime(ISOdatetime.j(start.year, start.jday, start.hr, start.min, start.sec),
"%Y:%j %H:%M:%OS3", tz="UTC", usetz=TRUE))
mtext(paste("zero:",timelbl), side=1, cex=0.7, font=1, adj=0.01, line=2.1)
#
if (n %% (nsacs/ncol) == 0){
mtext("time", side=1, line=2.5)
}
}
}
#' @rdname sacfiles
#' @export
fstart <- function(x, relative=FALSE) UseMethod("fstart")
#' @rdname sacfiles
#' @export
fstart.sac <- function(x, relative=NULL){
return(x$nzhour*3600 + x$nzmin*60 + x$nzsec + x$nzmsec*0.001)
}
#' @rdname sacfiles
#' @export
fstart.saclist <- function(x, relative=FALSE){
xst <- sapply(seq_along(x), function(n) fstart(x[[n]]))
if (relative){
xmin <- min(xst, na.rm=TRUE)
xmin.i <- which(xst==xmin)[1]
xst <- xst - xmin
attr(xst,"ref") <- xmin.i
attr(xst,"val") <- xmin
}
return(xst)
}
#' @rdname sacfiles
#' @export
sacunits <- function(x) UseMethod("sacunits")
#' @rdname sacfiles
#' @export
sacunits.sac <- function(x){
val <- x$units
if (!is.na(val) & val != 5){
switch(paste0("u"),
u6 = "Displacement, nm",
u7 = "Velocity, nm/sec",
u8 = "Acceleration, nm/sec/sec",
u50 = "Velocity, volts"
)
} else {
"Unknown"
}
}
#' @rdname sacfiles
#' @export
sacunits.saclist <- function(x){
sapply(seq_along(x), function(n) sacunits(x[[n]]))
}
#' @rdname sacfiles
#' @export
sync <- function(x) UseMethod("sync")
#' @rdname sacfiles
#' @export
sync.saclist <- function(x){
#
st <- fstart(x, relative=TRUE)
ref <- attr(st, "ref")
refval <- attr(st, "val")
#
reft <- list(nzhour = x[[ref]]$nzhour,
nzmin = x[[ref]]$nzmin,
nzsec = x[[ref]]$nzsec,
nzmsec = x[[ref]]$nzmsec,
b = x[[ref]]$b)
#
for (i in seq_len(length(x))){
x[[i]]$reftime <- c(ref, refval)
x[[i]]$nzhour <- reft$nzhour
x[[i]]$nzmin <- reft$nzmin
x[[i]]$nzsec <- reft$nzsec
x[[i]]$nzmsec <- reft$nzmsec
x[[i]]$b <- x[[i]]$b + st[i]
x[[i]]$e <- x[[i]]$e + st[i]
}
return(x)
}
#' @rdname sacfiles
#' @export
summaryStats <- function(x, trim=0, rel.time=NULL) UseMethod("summaryStats")
#' @rdname sacfiles
#' @export
summaryStats.sac <- function(x, trim=0, rel.time=NULL){
#print(str(x))
N <- x$N
if (N == 0){
stop("sac file contains no data (N == 0)")
}
dt <- x$dt
#..$ nzyear : int 2010
yr <- x$nzyear
#..$ nzjday : int 94
jd <- x$nzjday
#..$ nzhour : int 21
hrs <- x$nzhour
#..$ nzmin : int 42
mins <- x$nzmin
#..$ nzsec : int 11
#..$ nzmsec : int 4
secs <- x$nzsec
msecs <- x$nzmsec
#
#print(c(N,dt,yr,jd,hrs,secs,msecs))
#
# total relative second index (TRS) ==
# nzsec + nzmsec*0.001
trsecs <- round(secs + msecs/1000, 3)
# total absolute second index ==
# nzhour*3600 + nzmin*60 + TRS
#arsecs <- hrs*3600 + mins*60 + TRS
#
record.start <- ISOdatetime.j(yr, jd, hrs, mins, trsecs)
#
if (is.null(rel.time)){
rel.start <- difftime(record.start, record.start, units="sec")
} else {
stopifnot(length(rel.time)==1)
if (!is(rel.time, "POSIXt")){
rel.time <- ISOdatetime.j(tstr=paste(rel.time))
}
rel.start <- difftime(record.start, rel.time, units="sec")
}
rel.start <- unclass(rel.start)[1]
#
stopifnot(trim>=0 & trim<0.5)
#
if (length(trim)==1){
trim <- rep(trim,2)
}
lo <- floor(N * trim[1]) + 1
hi <- N - floor(N * trim[2])
#
dato <- x$amp
dat <- dato[lo:hi] # trimmed data
calib <- x$scale
calib.units <- sacunits(x)
#
fn <- fivenum(dat)
xsd <- sd(dat, na.rm=TRUE)
xmad <- mad(dat, na.rm=TRUE)
xmin <- fn[1]
lhinge <- fn[2]
xmed <- fn[3]
uhinge <- fn[4]
xmax <- fn[5]
xmax.loc <- which(dato==xmax)
xmin.loc <- which(dato==xmin)
xsum <- data.frame(start.year=yr,
start.jday=jd,
start.hr=hrs,
start.min=mins,
start.sec=trsecs,
start.relsec=rel.start,
N=N,
N.sec=N*dt,
n.lo=lo, n.hi=hi,
amp.calib.factor=calib,
amp.maximum=xmax,
amp.minimum=xmin,
amp.peak2peak.rms=abs(xmax - xmin)/2,
amp.hinge.upper=uhinge,
amp.median=xmed,
amp.hinge.lower=lhinge,
amp.MAD=xmad,
amp.SD=xsd,
relsec.max=(xmax.loc - 1)*dt + rel.start,
relsec.min=(xmin.loc - 1)*dt + rel.start
)
attr(xsum,"calib.units") <- calib.units
return(xsum)
}
#' @rdname sacfiles
#' @export
summaryStats.saclist <- function(x, trim=0, rel.time=NULL){
sapply(seq_along(x), function(n){summaryStats(x[[n]], trim, rel.time)})
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.