---
title: "Getting started with gmsp"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Getting started with gmsp}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 4)
```

```{r libs}
library(gmsp)
library(data.table)
```

This vignette walks through the signal-processing core of `gmsp` on a
synthetic acceleration record. The four entry points exercised are:

* `AT2TS()` — produce consistent AT / VT / DT.
* `getIntensity()` — compute 20+ scalar intensity measures.
* `TSL2PS()` — elastic SDOF response spectra from canonical `TSL`.
* `TS2IMF()` — empirical mode decomposition.

## Synthetic input

We build a 5-second, two-channel acceleration record sampled at
200 Hz, with two narrowband harmonic components per channel and a
mild amplitude envelope. Amplitudes are in mm/s² (the package's
canonical base unit).

```{r make-input}
NP <- 1000L
dt <- 1 / 200
t  <- seq.int(0, by = dt, length.out = NP)

env <- exp(-((t - 2.5) / 1.5)^2)

DT <- data.table(
  t  = t,
  H1 = env * (3.0 * sin(2 * pi *  5 * t) + 0.6 * sin(2 * pi * 20 * t)),
  H2 = env * (2.0 * sin(2 * pi *  7 * t) + 0.4 * sin(2 * pi * 17 * t))
)

str(DT)
```

## Run AT2TS

`AT2TS()` takes wide input (one time column plus one or more signal
columns). With `output = "TSL"` (the default), it returns a long table
keyed by `(t, s, ID, OCID)` where `ID ∈ {AT, VT, DT}` is the kinematic
quantity and `OCID` is the channel identifier inherited from the
input columns.

```{r at2ts}
TSL <- AT2TS(
  DT,
  units.source = "mm",
  units.target = "mm",
  Fmax        = 25,
  output      = "TSL",
  audit       = FALSE,
  verbose     = FALSE
)

TSL[, .N, by = .(ID, OCID)]
head(TSL[ID == "VT" & OCID == "H1"], 6)
```

A quick visual sanity check on the H1 channel:

```{r plot-at2ts, fig.alt = "AT, VT and DT for channel H1"}
op <- par(mfrow = c(3, 1), mar = c(4, 4, 2, 1))
plot(TSL[ID == "AT" & OCID == "H1", .(t, s)], type = "l",
     main = "AT (mm/s^2)", xlab = "", ylab = "")
plot(TSL[ID == "VT" & OCID == "H1", .(t, s)], type = "l",
     main = "VT (mm/s)",   xlab = "", ylab = "")
plot(TSL[ID == "DT" & OCID == "H1", .(t, s)], type = "l",
     main = "DT (mm)",     xlab = "t [s]", ylab = "")
par(op)
```

## Intensity measures

`getIntensity()` consumes a long TSL with columns `RSN, OCID, ID, t,
s`. It computes 20 + scalar measures per `(RSN, OCID, ID)` group: PGA
/ PGV / PGD, RMS, zero crossings, Arias intensity and its
positive / negative variants, three significant-duration measures
(D5–95, D5–75, D20–80), CAV and CAV5, mean period `Tm`, and the
derived indices EPI and PDI.

```{r intensity}
TSL[, RSN := "demo"]
IM <- getIntensity(TSL, units.source = "mm", units.target = "mm")

dcast(IM[IM %in% c("PGA", "PGV", "PGD", "AI", "D0595", "CAV")],
      OCID + IM ~ ., value.var = "value")
```

## Response spectrum

`TSL2PS()` integrates the SDOF equation of motion for a canonical `TSL`
table and reports PSA / PSV / SD. It derives grouping keys from `TSL`
metadata instead of requiring a public `BY` argument.

```{r ts2ps, fig.alt = "Pseudo-acceleration response spectrum"}
Tn  <- 10 ^ seq(log10(0.05), log10(3), length.out = 60)

PS <- TSL2PS(TSL[OCID == "H1"], xi = 0.05, Tn = Tn, output = "PSL")

head(PS)

plot(PS[ID == "PSA", .(Tn, S)], log = "x",
     type = "l", lwd = 2,
     xlab = "Tn [s]", ylab = "PSA [mm/s^2]",
     main = "5%-damped pseudo-acceleration spectrum (H1)")
```

## IMF decomposition

`TS2IMF()` decomposes one signal into intrinsic mode functions
(EMD / EEMD / VMD) and a residue, optionally returning a reconstruction
filtered by frequency content. Default engine is VMD.

```{r imf, fig.alt = "First two IMFs of the AT H1 signal"}
AT_H1 <- TSL[ID == "AT" & OCID == "H1", .(t, s)]
IMFs  <- TS2IMF(AT_H1, method = "vmd", K = 6, output = "TSW")

names(IMFs)
head(IMFs[, 1:5])

op <- par(mfrow = c(2, 1), mar = c(4, 4, 2, 1))
plot(IMFs$t, IMFs$IMF1, type = "l",
     main = "IMF1", xlab = "", ylab = "")
plot(IMFs$t, IMFs$IMF2, type = "l",
     main = "IMF2", xlab = "t [s]", ylab = "")
par(op)
```

## Where to go next

Four vignettes ship with the package:

```r
vignette("signal-processing",  package = "gmsp")  # AT2TS / VT2TS / DT2TS math
vignette("imfs",               package = "gmsp")  # TS2IMF decomposition (EMD / EEMD / VMD)
vignette("spectra",            package = "gmsp")  # TSL2PS elastic SDOF spectra
vignette("intensity-measures", package = "gmsp")  # getIntensity output details
vignette("database",           package = "gmsp")  # optional file-based indexing layer
```

In-session help: `?AT2TS`, `?TS2IMF`, `?TSL2PS`, `?getIntensity`, or
`help(package = "gmsp")`.

Rendered documentation: <https://averriK.github.io/gmsp/>.
