| Type: | Package |
| Title: | Ground Motion Signal Processing |
| Version: | 1.1.1 |
| Description: | Implements short-time Fourier transform (STFT) based processing of strong-motion time series: time-grid regularisation, STFT-window and anti-alias-resampling strategy selection, edge tapering, and frequency-domain integration and differentiation, mapping a single input (acceleration, velocity, or displacement) to a consistent triplet under a chosen analysis bandwidth. Also provides intrinsic-mode-function decomposition via empirical mode decomposition (EMD), ensemble EMD (EEMD), and variational mode decomposition (VMD) with optional band-rule filtering; elastic single-degree-of-freedom (SDOF) domain-normalised acceleration, velocity, and displacement response spectra from their corresponding time-series domains by exact state-space integration; intensity measures including peak, root-mean-square (RMS), Arias intensity, significant-duration, cumulative absolute velocity, mean period, and the derived indices earthquake destructiveness potential (EPI) and power-of-input (PDI); and D50 and D100 horizontal response spectra. Methods: Huang et al. (1998) <doi:10.1098/rspa.1998.0193>, Wu and Huang (2009) <doi:10.1142/S1793536909000047>, Dragomiretskiy and Zosso (2014) <doi:10.1109/TSP.2013.2288675>, Boore (2010) <doi:10.1785/0120090400>. An optional indexing layer parses provider files in formats including 'PEER' 'NGA-West2' 'AT2', 'CESMD' 'V2'/'V2c', 'NWZ' 'V2A', Geological Survey of Canada 'TR', 'IGP'/'UCR' 'AC' variants, and generic two-column ASCII text, normalises components, writes per-record CSV (comma-separated values) and JSON (JavaScript Object Notation) pairs, and computes per-record intensity tables. |
| License: | AGPL (≥ 3) |
| URL: | https://kanameishi.github.io/gmsp/ |
| Encoding: | UTF-8 |
| Depends: | R (≥ 4.1.0) |
| Imports: | data.table, digest, expm, jsonlite, Matrix, osqp, parallel, pracma, seewave, signal, stats, tools, utils, xemd |
| Config/roxygen2/version: | 8.1.1 |
| Suggests: | bit64, knitr, rmarkdown |
| VignetteBuilder: | knitr |
| SystemRequirements: | tar (for archived record metadata) |
| NeedsCompilation: | no |
| Packaged: | 2026-11-11 21:53:45 UTC; averrik |
| Author: | Alejandro Daniel Verri
|
| Maintainer: | Alejandro Daniel Verri <averri@fi.uba.ar> |
| Repository: | CRAN |
| Date/Publication: | 2026-11-11 22:40:02 UTC |
Accumulate normalized intensity histories
Description
Computes cumulative prefixes from acceleration rows and divides each record/component history by its own maximum.
Usage
accumulateIntensityTSL(TSL, by, ID, unitsSource, unitsTarget)
Arguments
TSL |
A table with columns |
by |
Character vector of record metadata columns; |
ID |
Cumulative quantity: exactly |
unitsSource, unitsTarget |
Required source and target length bases:
|
Details
At least one AT history is required. Each history requires at least two finite numeric samples and unique times; rows are sorted by t before calculation. Missing columns, duplicate keys and invalid units cause errors.
Prefix sums use the mean time step and include the first sample. AI sums squared acceleration with the Arias scale; CAV sums absolute acceleration. CAV5 includes absolute acceleration at least 0.05 times standard gravity. This CAV5 cutoff is the inherited gmsp definition.
The input is copied. The function reads or writes no files, uses no random numbers and changes no session options.
Value
A new data.table with columns by,OCID,ID,t,s, ordered by
metadata, component and time. ID contains the requested quantity and s
contains dimensionless ratios. A zero or nonfinite cumulative maximum
produces NA_real_ throughout that history, including arithmetic overflow
from finite samples.
See Also
Examples
TSL <- data.table::data.table(
RecordID = "R1", OCID = "H1", ID = "AT",
t = seq(0, 1, by = 0.25), s = c(0, 400, 500, 400, 0))
accumulateIntensityTSL(TSL, by = "RecordID", ID = "CAV5",
unitsSource = "mm", unitsTarget = "mm")
Equalize component sample counts
Description
Pads shorter components with trailing zeros for max alignment, or truncates longer components for min alignment. Alignment operates by row count without interpolating time.
Usage
alignComponents(data, align = "max")
Arguments
data |
A long data.table with |
align |
Either |
Details
Padding uses the interval between the first two samples of the first OCID. Empty input, unknown alignment and a nonfinite or nonpositive interval needed for padding raise errors.
Value
A list with DT, the aligned table, and NP, the final
sample count per component. The input table remains unchanged.
Examples
Record <- data.table::data.table(
t = c(0, 0.01, 0.02, 0, 0.01), OCID = c("H1", "H1", "H1", "H2", "H2"),
DIR = c("H1", "H1", "H1", "H2", "H2"), s = c(1, 2, 3, 4, 5))
Padded <- alignComponents(Record, align = "max")
Padded$NP
print(Padded$DT)
alignComponents(Record, align = "min")$NP
Archive a station's provider files
Description
Creates raw.owner.tar.gz from raw.owner and removes the source directory after confirming that the archive exists and has a nonempty listing.
Usage
archiveRawOwner(path)
Arguments
path |
Station folder containing raw.owner. |
Details
The working directory is restored on exit. The archive check is a listing check and does not compare extracted file bytes. A failed creation or listing leaves the source directory and removes the archive.
Value
An invisible logical value: TRUE after archiving, FALSE when the source directory is absent or the destination exists, and NA for a treated archive creation or listing failure.
Examples
Station <- tempfile("archiveRawOwner")
dir.create(file.path(Station, "raw.owner"), recursive = TRUE)
writeLines(c("header", "Event, date, station, H1", "units",
"NPTS= 4, DT= 0.01 SEC", "1.0 2.0 3.0 4.0"),
file.path(Station, "raw.owner", "H1.AT2"))
print(archiveRawOwner(Station))
list.files(Station)
utils::untar(file.path(Station, "raw.owner.tar.gz"), list = TRUE)
unlink(Station, recursive = TRUE)
Assess compatibility of a scaled suite
Description
Calculates record diagnostics and a suite summary against a target band, preserving the input tables and performing no file access.
Usage
assessCompatibility(PSW, target, scale, OCID, factorMin, factorMax)
Arguments
PSW |
A data.table of scaled spectra with |
target |
A table with finite, unique, non-negative |
scale |
A data.table with unique |
OCID |
Component identifier: |
factorMin |
Finite non-negative lower record-factor bound. |
factorMax |
Upper record-factor bound, at least |
Details
Duplicate RecordID/Tn keys in PSW are errors.
Calculations use matching periods without interpolation; an empty
intersection is an error, and nTn reports its size for each record.
When a record lacks the PGA period, its PGA value, ratios and status
remain NA.
Band containment uses 1e-6 * pmax(1, abs(Sa.high)); relative
violations use the band limits without that tolerance.
Factor-bound flags use an absolute difference below 1e-8.
Value
A list of data.tables: record contains record keys,
nTn, PGA values and target ratios, relative PSA RMSE, band
containment and violations, scaleFactor, scaleAtMin,
scaleAtMax and PGA status, ordered by decreasing PGA.final.
summary contains record counts by PGA status and factor bounds,
and median or extreme values of record RMSE, containment and violation.
See Also
Examples
Target <- data.table::data.table(Tn = c(0, 1), Sa.low = 0.50 * 9806.65,
Sa.mean = 0.84 * 9806.65, Sa.high = 0.95 * 9806.65)
PSW <- data.table::data.table(RecordID = rep(c("R1", "R2"), each = 2),
Tn = c(0, 1, 0, 1), PSA.H1 = c(7000, 8500, 4000, 9800))
Scale <- data.table::data.table(RecordID = c("R1", "R2"), scaleFactor = c(1, 1.6))
Compatibility <- assessCompatibility(PSW, target = Target, scale = Scale,
OCID = "H1", factorMin = 0.5, factorMax = 1.6)
print(Compatibility$record[, c("RecordID", "PGA.final", "PSA.inside",
"scaleAtMax", "status")])
print(Compatibility$summary[, c("records", "nPGA.inside", "nPGA.below",
"nScaleAtMax")])
Assess coordinate and distance metadata
Description
Returns flagged rows with the first applicable reason, preserving the input.
Usage
assessDistances(data, repiOutlier)
Arguments
data |
Table with numeric EventLatitude, EventLongitude, StationLatitude, StationLongitude, EventDepth, Repi and Rhyp. Repi and Rhyp use kilometres. Additional columns are retained. |
repiOutlier |
Finite scalar cutoff in kilometres for Repi. |
Details
Reasons follow this precedence: latNA, lonNA, eventLatOOR, stationLatOOR, eventLonOOR, stationLonOOR, depthNeg, repiOut, geomBad. Absolute coordinate limits are 90 for latitude and 180 for longitude. geomBad uses Rhyp less than Repi minus 0.01 kilometres; this is the diagnostic rule. Missing coordinates are flagged, while missing depth or distances do not by themselves produce a reason. Missing required columns, nonnumeric columns and an invalid cutoff are input errors. The operation performs no file access.
Value
A data.table containing flagged rows in input order, with Reason.
See Also
Examples
Records <- data.frame(RecordID = c("R1", "R2", "R3", "R4"),
EventLatitude = c(10, NA, 10, 10), EventLongitude = 20,
StationLatitude = 10.4, StationLongitude = 20.1, EventDepth = 30,
Repi = c(45, 45, 450, 45), Rhyp = c(54, 54, 451, 40))
assessDistances(Records, repiOutlier = 300)
Assess provider parsing by station
Description
Reads each station of an owner through parseRecord and reports its status.
Usage
assessParsers(records, owner, path)
Arguments
records |
Record metadata with OwnerID, EventID, StationID and the FileID rows required by parseRecord. |
owner |
One nonempty OwnerID string. |
path |
Nonempty path to the records root, passed to parseRecord. |
Details
Status is OK for a returned parser result, with its row and column counts; FAIL for an error; WARN for a warning. The latter statuses retain conditionMessage as reason. Missing grouping columns or invalid owner/path arguments are input errors. The operation writes no extracted records.
Value
A data.table with OwnerID, EventID, StationID, status and reason, in first-appearance station order. An owner without rows returns an empty table with these columns.
See Also
Examples
Root <- tempfile("assessParsers")
Station <- file.path(Root, "NGAW", "E1", "S1", "raw.owner")
dir.create(Station, recursive = TRUE)
writeLines(c("header", "Event, date, station, H1", "units",
"NPTS= 4, DT= 0.01 SEC", "1.0 2.0 3.0 4.0"),
file.path(Station, "H1.AT2"))
Records <- data.table::data.table(OwnerID = "NGAW", EventID = "E1",
StationID = c("S1", "S2"), FileID = "H1.AT2")
Status <- assessParsers(Records, owner = "NGAW", path = Root)
print(Status[, c("StationID", "status")])
unlink(Root, recursive = TRUE)
Assess station velocity metadata
Description
Returns flagged rows with the first applicable station-velocity reason, preserving the input.
Usage
assessSite(data, vs30Low, vs30High)
Arguments
data |
Table with numeric StationVs30 in metres per second. Additional columns are retained. |
vs30Low, vs30High |
Finite scalar cuts, ordered from low to high, in metres per second. |
Details
Missing StationVs30 gives vs30NA; values below vs30Low give vs30Low, and values above vs30High give vs30High, in that precedence. Values equal to a cut are not flagged. A missing or nonnumeric StationVs30 column and invalid cuts are input errors. The operation performs no file access.
Value
A data.table containing flagged rows in input order, with Reason.
See Also
Examples
Stations <- data.frame(StationID = c("S1", "S2", "S3", "S4"),
StationVs30 = c(NA, 150, 400, 2000))
assessSite(Stations, vs30Low = 180, vs30High = 1500)
Build provider file indexes
Description
Reads record.json from each station's raw.owner directory or its raw.owner.tar.gz archive and writes one RawFileTable CSV per owner.
Usage
buildRawFileTable(pathRecords, pathIndex, owners = NULL)
Arguments
pathRecords |
Records root containing owner, event and station folders. |
pathIndex |
Existing destination folder for |
owners |
Owner identifiers; NULL scans immediate directories of pathRecords. |
Details
Columns are OwnerID, EventID, StationID, ComponentID, FileID, NP, dt, Fs, Units, HP, LP and isArray, ordered by event, station and component. Missing metadata become typed NA and extra fields are dropped. isArray indicates more than three component rows in the provider metadata.
A station failure retains its cause and path. Valid rows are published; an error of class modulePartialPublication then carries failures, the partial result and destination path. Counts are not returned as complete after such a failure. Archive metadata are read without extracting files.
Value
An invisible named list of row counts for the owners written.
Examples
Root <- tempfile("buildRawFileTable")
Station <- file.path(Root, "records", "NGAW", "E1", "S1", "raw.owner")
Index <- file.path(Root, "index")
dir.create(Station, recursive = TRUE)
dir.create(Index)
Metadata <- list(Event = list(EventID = "E1"), Station = list(StationID = "S1"),
Record = data.frame(ComponentID = c("HNE", "HNN", "HNZ"),
FileID = c("HNE.AT2", "HNN.AT2", "HNZ.AT2"),
NP = 4L, dt = 0.01, Fs = 100, Units = "g"))
jsonlite::write_json(Metadata, file.path(Station, "record.json"), auto_unbox = TRUE)
Counts <- buildRawFileTable(file.path(Root, "records"), pathIndex = Index)
str(Counts)
data.table::fread(file.path(Index, "RawFileTable.NGAW.csv"))
unlink(Root, recursive = TRUE)
Build raw acceleration intensity indexes
Description
Measures raw AT records and writes RawIntensityTable.<OwnerID>.csv,
with one row per RecordID and DIR and the provider OCID retained.
Usage
buildRawIntensityTable(
pathRecords,
pathIndex,
owners = NULL,
incremental = TRUE,
force = FALSE
)
Arguments
pathRecords |
Records root containing owner, event and station folders. |
pathIndex |
Existing destination folder for the index files. |
owners |
Owner identifiers; NULL scans immediate directories of pathRecords. |
incremental |
Reuses records already present in the index when TRUE. |
force |
Ignores the incremental cache when TRUE. |
Details
The index contains RecordID, DIR, OCID, AI, AId, AIu, ARMS, ATn, ATo, AZC, CAV, CAV5, D0575, D0595, D2080, Dmax, EPI, Fs, NP, PDI, PGA, TmA and dt, ordered by RecordID and DIR. Values use a millimetre length basis. Duration and period fields use one decimal place and dt uses four; the remaining measure fields are rounded to integers.
VT and DT stations are omitted with a warning naming the station and quantity. A station failure retains its cause and path. Valid rows are published; an error of class modulePartialPublication then carries failures, the partial result and destination path. Existing files are replaced when the owner has new intensity rows.
Value
An invisible named list of row counts for the owners written.
Examples
Root <- tempfile("buildRawIntensityTable")
Raw <- file.path(Root, "records", "NGAW", "E1", "S1", "raw")
Index <- file.path(Root, "index")
dir.create(Raw, recursive = TRUE)
dir.create(Index)
Time <- seq(0, 5, by = 0.01)
Envelope <- sin(pi * Time / max(Time))^2
data.table::fwrite(data.table::data.table(
HNE = 1200 * Envelope * sin(2 * pi * 1.5 * Time),
HNN = 800 * Envelope * sin(2 * pi * 2.5 * Time),
HNZ = 400 * Envelope * sin(2 * pi * 4 * Time)), file.path(Raw, "AT.R1.csv"))
jsonlite::write_json(list(RecordID = "R1", DIR = c("H1", "H2", "UP"),
OCID = c("HNE", "HNN", "HNZ"), dt = 0.01), file.path(Raw, "AT.R1.json"),
auto_unbox = TRUE)
Counts <- buildRawIntensityTable(file.path(Root, "records"), pathIndex = Index)
str(Counts)
Intensity <- data.table::fread(file.path(Index, "RawIntensityTable.NGAW.csv"))
print(Intensity[, c("RecordID", "DIR", "OCID", "PGA", "AI", "D0595")])
unlink(Root, recursive = TRUE)
Build raw record indexes
Description
Reads AT, VT and DT raw JSON sidecars and writes
RawRecordTable.<OwnerID>.csv for each owner with records.
Usage
buildRawRecordTable(pathRecords, pathIndex, owners = NULL)
Arguments
pathRecords |
Records root containing owner, event and station folders. |
pathIndex |
Existing destination folder for the index files. |
owners |
Owner identifiers; NULL scans immediate directories of pathRecords. |
Details
Columns are RecordID, EventID, StationID, OwnerID, NP, Fs and pad, ordered by event and station. NP is the maximum pre-alignment count from the sidecar, and pad is the difference between maximum and minimum counts. Under truncation, NP does not describe the CSV row count.
A station failure retains its cause and path. Valid rows are published; an error of class modulePartialPublication then carries failures, the partial result and destination path.
Value
An invisible named list of row counts for the owners written.
Examples
Root <- tempfile("buildRawRecordTable")
Raw <- file.path(Root, "records", "NGAW", "E1", "S1", "raw")
Index <- file.path(Root, "index")
dir.create(Raw, recursive = TRUE)
dir.create(Index)
jsonlite::write_json(list(RecordID = "R1", OwnerID = "NGAW", EventID = "E1",
StationID = "S1", NP = c(4, 4, 3), Fs = 100), file.path(Raw, "AT.R1.json"),
auto_unbox = TRUE)
Counts <- buildRawRecordTable(file.path(Root, "records"), pathIndex = Index)
str(Counts)
data.table::fread(file.path(Index, "RawRecordTable.NGAW.csv"))
unlink(Root, recursive = TRUE)
Build acceleration, velocity, and displacement histories
Description
buildTSL() processes one measured quantity into acceleration (AT),
velocity (VT), and displacement (DT) on a common time grid per record.
Records are identified by the explicit metadata columns in by and their
channels by OCID.
Usage
buildTSL(
TSL,
by,
unitsSource,
unitsTarget,
fmax,
windowLength,
overlap,
astop0,
apass0,
astopLP,
apassLP,
kNyq = NULL,
isRaw = TRUE,
flatZeros = FALSE,
trimZeros = FALSE,
removeMean = FALSE,
forceRegularization = FALSE,
includeWarnings = TRUE,
derivate = "freq",
lowPass = TRUE
)
Arguments
TSL |
A data.table with columns |
by |
Character vector of metadata columns identifying a record.
|
unitsSource |
Input length basis when |
unitsTarget |
Required target length basis: |
fmax |
Required finite positive frequency of interest in Hz. |
windowLength |
Required positive integer nominal STFT window length
in samples. The strategy can adjust the length; the initial request is
capped for |
overlap |
Required overlap percentage in |
astop0, apass0 |
Required finite positive normalized amplitude thresholds for the channel edge tapers. |
astopLP, apassLP |
Required finite positive magnitudes for the resampling antialias and derivative low-pass filters. The controls require astopLP < apassLP < 1. |
kNyq |
|
isRaw |
Logical scalar. Raw input is converted from |
flatZeros |
Logical scalar enabling edge tapers for processed input.
For |
trimZeros |
Logical scalar selecting final nonzero window support.
|
removeMean |
Logical scalar enabling removal of channel means at the processing stages of the measured quantity. |
forceRegularization |
Logical scalar forcing interpolation of processed input. Irregular or non-rational grids are always regularized. |
includeWarnings |
Logical scalar enabling strategy warnings. Diagnostics do not alter the computed amplitudes. |
derivate |
Derivative method for |
lowPass |
Logical scalar enabling the derivative low-pass with
|
Details
Each channel requires at least three samples; derivatives require more than four samples on the grid used by the derivative. Frequency-domain integration and differentiation set the zero-frequency term to zero. Tapering, resampling, and removal of means affect the processed histories. The returned quantities are not exact algebraic inverses of the input.
Invalid keys, non-finite samples, incompatible channel grids, unsupported units, and invalid controls cause an error. Errors during record processing carry the record context. The function reads or writes no files, uses no random numbers, and changes no working directory, options, or environment.
Value
A new data.table with columns by,OCID,ID,t,s, ordered by record,
channel, quantity (AT, VT, DT), and time. The common grid starts at
zero for each record. Amplitudes use unitsTarget/s^2, unitsTarget/s,
and unitsTarget, respectively. The input is unchanged.
See Also
normalizeTSL(), widenTSL(), lengthenTSW()
Examples
Time <- seq(0, 5, by = 0.01)
TSL <- data.table::data.table(
OCID = "H1", ID = "AT", t = Time,
s = 120 * sin(pi * Time / max(Time))^2 * sin(2 * pi * 1.5 * Time)
)
Histories <- buildTSL(
TSL, by = character(), unitsSource = "mm", unitsTarget = "mm", fmax = 5,
windowLength = 128, overlap = 75,
astop0 = 1e-3, apass0 = 1e-3,
astopLP = 1e-3, apassLP = 0.98,
includeWarnings = FALSE
)
unique(Histories$ID)
Compute response spectra from canonical time series
Description
Computes PSA, PSV and SD from AT, VT and DT as separate excitations. Each ordinate retains the units of its source domain. The zero-period anchor is the peak absolute value of the regularized source signal.
Usage
computeSpectraTSL(
TSL,
by,
xi,
Tn,
includeD50 = FALSE,
includeD100 = FALSE,
nTheta
)
Arguments
TSL |
A table with |
by |
Character vector of record metadata columns, or
|
xi |
Nonempty numeric vector of finite damping ratios in |
Tn |
Nonempty numeric vector of finite positive periods in seconds. Zero is reserved for the internally added peak-value anchor. |
includeD50 |
Logical scalar selecting the median rotated component. |
includeD100 |
Logical scalar selecting the maximum rotated component. |
nTheta |
Number of angles in [0,pi), required when a rotated component is selected; an integer of at least two. |
Details
Each domain is regularized independently to the minimum rationalized time step and a zero time origin. The oscillator starts from zero state and uses the final sample of each interval as input. PSV and SD use VT and DT excitations, respectively.
Rotations require H1 and H2 on identical input time grids in each domain. D50 uses the median with quantile type 7; D100 uses the maximum across the selected angles, including the peak-value anchor. Original components remain in the result. Vector xi rejects an input column named xi. Duplicate sample keys and invalid controls are errors. The input is copied; the operation uses no random numbers or files and does not change session options. Units are preserved without conversion.
Value
A new data.table with by,OCID,Tn,ID,S, ordered by metadata,
component, spectral ID and period. Vector xi adds an xi column
after the metadata and preserves the requested damping order within
each record. Repeated periods and damping ratios remain repeated.
See Also
Examples
t <- seq(0, 1, by = 0.01)
TSL <- data.table::rbindlist(list(
data.table::data.table(t = t, s = sin(2 * pi * t), ID = "AT", OCID = "H1"),
data.table::data.table(t = t, s = cos(2 * pi * t), ID = "VT", OCID = "H1"),
data.table::data.table(t = t, s = sin(pi * t), ID = "DT", OCID = "H1")))
computeSpectraTSL(TSL, by = character(), xi = 0.05, Tn = c(0.1, 0.2))
Decompose acceleration records into modes
Description
Regularizes acceleration records and composes the native xemd decomposition tables.
Usage
decomposeRecords(TSL, method, control, by)
Arguments
TSL |
A data.table containing t in seconds, finite real samples s, character ID and OCID, and record metadata. Only ID AT is decomposed. Present components form a nonempty subset of H1, H2, and UP. Each record has at least three unique times on a common component grid; other metadata are constant within each component. |
method |
Historical name vmd or eemd, or a name returned by xemd::listDecompositions(). |
control |
Named list without duplicate names. Historical vmd requires k, alpha, tau, DC, init, tolerance and maxIterations; init must be zero. Historical eemd requires k, noise.amp, trials and an explicit sifting list. Native controls follow the selected xemd method; signal, samplingInterval, noise and noiseChannels are derived and cannot be supplied. |
by |
Distinct metadata column names identifying a record; character() declares one record. |
Details
Regularization uses the smallest rationalized time difference, monoH.FC interpolation and zero origin before translating controls. Historical vmd uses zero initial centers and converts alpha by samplingInterval^2 / (8 * pi^2); its relative tolerance is explicit, and tol is not accepted. Historical eemd converts absolute noise.amp to noise.amp / sd(signal) for each component, requiring positive finite sd; it uses divisor realizations and maxModes equal to k. Conflicting maxModes is an error. sifting follows its explicit xemd stopRule and its documented defaults; wave and type5 are not translated. Historical vmd calls ascend by effective interval, then record and component; historical eemd calls ascend by record and component. Native methods follow decomposeTSL ordering. Tables are ordered by by, OCID, ID, mode or boundary, and t when present. Units are transported without conversion. Stochastic methods consume the caller's random stream. The function sets no seed, restores no RNG state, starts no parallel workers and writes no files. Inputs are preserved. Invalid data or controls cause errors; xemd failures retain their classes and group, with the moduleFailure family and operation. Native diagnostics and termination retain non-convergence and iteration limits.
Value
A named list of data.tables with signal and modes and the fields residue, fitResidual, meanNoise, diagnostics, termination, centers, maskFrequencies or boundaries returned by the method. signal contains the effective input. Mode indices and optional fields retain their native meaning.
See Also
reconstructRecords(), xemd::decomposeTSL()
Examples
Time <- seq(0, 9, length.out = 1000)
TSL <- data.table::data.table(RecordID = "R1", OCID = "H1", ID = "AT", t = Time,
s = sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time,
Units = "mm")
Control <- list(k = 3, alpha = 2000, tau = 0.5, DC = FALSE, init = 0,
tolerance = 1e-6, maxIterations = 98)
Decomposition <- decomposeRecords(TSL, method = "vmd", control = Control,
by = "RecordID")
names(Decomposition)
print(Decomposition$centers)
head(Decomposition$modes)
Describe the Installed Module
Description
Return the installed identity of this module.
Usage
describeModule()
Value
A list containing package and version.
Export project products
Description
Writes selected time series and product tables, and copies available metadata and HTML files to a delivery directory.
Usage
exportProject(file = file.path("gmsp", "export.json"), root = getwd())
Arguments
file |
Path to the JSON export contract, resolved against |
root |
Existing project directory. |
Details
The contract requires path.out and selects path.source or database
paths with an explicit selection.
A source directory requires TSW.csv and IMW.csv; PSW.csv
is optional.
ID defaults to AT and DIR to H1.
A raw database supports AT.
An explicit path.index identifies a MasterIndex CSV file.
HTML copies preserve subdirectories and reject duplicate relative paths
within the plot or audit inputs.
A nonempty destination requires override=true, which preserves
unrelated files.
The working directory is restored after completion or failure.
Value
Invisible integer zero on completion; usage, execution or partial publication failures signal conditions.
Examples
Root <- tempfile("exportProject")
dir.create(file.path(Root, "source"), recursive = TRUE)
dir.create(file.path(Root, "gmsp"))
data.table::fwrite(data.table::data.table(RecordID = "001", t = c(0, 0.1, 0.2),
AT.H1 = c(0, 1, -1), AT.H2 = c(1, 0, -1)), file.path(Root, "source", "TSW.csv"))
data.table::fwrite(data.table::data.table(RecordID = "001", OCID = c("H1", "H2"),
PGA = c(100, 200)), file.path(Root, "source", "IMW.csv"))
jsonlite::write_json(list(path = list(source = "source", out = "delivery"),
DIR = c("H1", "H2")), file.path(Root, "gmsp", "export.json"), auto_unbox = TRUE)
exportProject(root = Root)
list.files(file.path(Root, "delivery"), recursive = TRUE)
data.table::fread(file.path(Root, "delivery", "TSW.001.AT.H1.csv"))
unlink(Root, recursive = TRUE)
Extract a provider record to raw files
Description
Reads and classifies one provider record without rotation, converts its amplitudes to a millimetre length basis and writes a CSV and JSON pair.
Usage
extractRecord(record, path, align = "max", kind = NULL)
Arguments
record |
Table for one owner, event and station, with FileID and Units; NetworkID is retained in the sidecar when supplied. |
path |
Records root containing OwnerID/EventID/StationID/raw.owner. |
align |
Alignment by sample count: "max" pads with trailing zeros; "min" truncates. Neither choice interpolates time. |
kind |
Quantity override AT, VT or DT; NULL derives the quantity from Units. An override still requires recognisable Units. |
Details
The CSV retains provider OCID columns and omits time, and its lines end with LF on every system. RecordID is the first 16 characters of the MD5 digest of the CSV bytes, so it does not depend on the system. The JSON stores DIR, OCID and pre-alignment NP arrays in H1, H2, UP order; peaks are measured after alignment. Its dt and Fs use nine and six decimal places, respectively, and Units is "mm".
Existing raw contents are removed after classification and unit resolution, before alignment and writing. A later failure can leave partial products; extraction is not atomic. The supplied table is not modified.
Value
Absolute path to the written CSV, or NULL when classification or unit interpretation cannot produce a record.
Examples
Root <- tempfile("extractRecord")
Station <- file.path(Root, "NGAW", "E1", "S1", "raw.owner")
dir.create(Station, recursive = TRUE)
Samples <- c(HNE = "0.01 0.03 -0.02 0.01", HNN = "0.02 -0.01 0.01 0",
HNZ = "0 0.01 -0.01 0")
for (Channel in names(Samples)) {
writeLines(c("header", paste0("Event, date, station, ", Channel), "units",
"NPTS= 4, DT= 0.01 SEC", Samples[[Channel]]),
file.path(Station, paste0(Channel, ".AT2")))
}
Record <- data.table::data.table(OwnerID = "NGAW", EventID = "E1",
StationID = "S1", FileID = paste0(names(Samples), ".AT2"), Units = "g")
CSV <- extractRecord(Record, path = Root)
basename(CSV)
data.table::fread(CSV)
Sidecar <- jsonlite::read_json(sub("[.]csv$", ".json", CSV), simplifyVector = TRUE)
str(Sidecar[c("DIR", "OCID", "NP", "PGA", "dt", "Units")])
unlink(Root, recursive = TRUE)
Fit modal factors against a response-spectrum band
Description
Fits the retained modes of one component of one record, then restores signal energy in the final reconstruction.
Usage
fitModalFactor(
IMF,
target,
source,
key,
OCID,
xi,
fmax,
kNyq,
signalControl,
factorMin,
factorMax,
criterion,
unitsSource,
unitsTarget,
includeResidue = TRUE
)
Arguments
IMF |
Table for one record with OCID, t, signal, optional |
target |
Table with unique nonnegative Tn in seconds and finite positive Sa.low, Sa.mean and Sa.high, in that order at each period. The band includes Tn = 0 and positive periods; amplitudes use unitsTarget/s^2. |
source |
Wide time-series table for the same record, with its key
columns, t and |
key |
One-row table with RecordID, OwnerID, EventID and StationID, plus ProcessID when present in the context. Missing IMF key columns are filled from this row; conflicting values are errors. |
OCID |
Component to fit: "H1", "H2" or "UP". |
xi |
Positive finite damping ratio accepted by computeSpectraTSL. |
fmax |
Positive finite frequency of interest in Hz. |
kNyq |
Positive finite sampling-frequency multiplier. |
signalControl |
Named list with windowLength, overlap, astop0, apass0, astopLP and apassLP, as in buildTSL. Optional flatZeros, trimZeros, removeMean, forceRegularization and includeWarnings retain their buildTSL defaults; duplicate or other fields are errors. |
factorMin |
Finite lower modal-factor bound in (0,1]. |
factorMax |
Upper modal-factor bound at least one; Inf is admitted. |
criterion |
Explicit xemd selection list: rule "band" with fMin and fMax in Hz, or rule "energyFraction" with minimum, and action "keep" or "remove". Band limits are finite with 0 <= fMin <= fMax; minimum is finite and nonnegative. At least one mode must remain; selection by mode name or index is not admitted. |
unitsSource, unitsTarget |
Source and destination length bases: "mm", "cm" or "m", matched case-insensitively. Source histories and IMF amplitudes are converted to the destination basis. |
includeResidue |
Logical scalar, TRUE by default, retaining the residue when present with a fixed coefficient of one, outside the modal optimization and its factor bounds. Final energy restoration applies to the complete reconstruction, including the residue. |
Details
Modes are measured and selected through xemd. The objective uses relative spectral RMSE, squared relative band violations and a 0.01 weight on mean squared log-factor movement. L-BFGS-B starts with factors equal to one and maxit = 1. Energy restoration applies after optimization.
In metrics, status is done and convergence and message retain the stats::optim result: convergence 0 is successful completion, 1 means that the iteration limit maxit was reached, and 51 and 52 are a warning and an error of L-BFGS-B explained by message. message is the optimizer text, such as NEW_X, or NA when the optimizer returns none. With maxit = 1, code 1 is the expected result and does not indicate a failure. The convergence code does not change status.
Invalid keys, controls, samples or target bands cause an error with record context. Zero reconstruction energy is an error. Dependency conditions retain their classes. Inputs are preserved; the operation reads or writes no files and uses no random numbers.
Value
A list with TSW and PSW for the fitted component; PSA with RecordID, kind (source/start/final), Tn and Sa; coeff with the record keys, IMF, b0, b, ratio, energyFactor and stageFactor; metrics with optimizer status and fit diagnostics; and eval in objective-call order. Time histories and spectra are ordered by record and time or period; coefficients follow the retained modal order, then the residue. Its row has b0, b and ratio equal to one, and stageFactor equal to energyFactor.
See Also
fitRecordFactor(), assessCompatibility(), buildTSL(),
xemd::selectModesTSL()
Examples
Key <- data.table::data.table(RecordID = "R1", OwnerID = "A", EventID = "E1",
StationID = "S1")
Time <- seq(0, 4, by = 0.01)
Mode <- 1000 * sin(2 * pi * Time)
Residue <- 100 * sin(pi * Time)
IMF <- data.table::data.table(OCID = "H1", t = Time, signal = Mode + Residue,
IMF1 = Mode, residue = Residue)
Source <- data.table::data.table(Key, t = Time, AT.H1 = Mode + Residue,
VT.H1 = 0, DT.H1 = 0)
Target <- data.table::data.table(Tn = c(0, 1, 2), Sa.low = 1000,
Sa.mean = 2000, Sa.high = 3000)
Control <- list(windowLength = 128, overlap = 75, astop0 = 0.001, apass0 = 0.001,
astopLP = 0.001, apassLP = 0.98, includeWarnings = FALSE)
Fit <- fitModalFactor(IMF, target = Target, source = Source, key = Key,
OCID = "H1", xi = 0.05, fmax = 25, kNyq = 4, signalControl = Control,
factorMin = 0.001, factorMax = Inf,
criterion = list(rule = "energyFraction", minimum = 0, action = "keep"),
unitsSource = "mm", unitsTarget = "mm")
print(Fit$coeff[, c("IMF", "b", "energyFactor", "stageFactor")])
print(Fit$PSA[Fit$PSA$kind == "final"])
print(Fit$metrics[, c("status", "convergence", "RMSE.start", "RMSE.final")])
Fit suite record-scaling factors
Description
Fits one bounded scale factor per record with a quadratic program against a target response-spectrum band, without modifying the input tables.
Usage
fitRecordFactor(
PSA,
target,
records,
factorMin,
factorMax,
bandWeight,
deficitWeight
)
Arguments
PSA |
A data.table with character |
target |
A table with |
records |
Character vector of distinct completed record identities, in the requested output order. |
factorMin |
Finite non-negative lower factor bound. |
factorMax |
Upper factor bound, at least |
bandWeight |
Finite non-negative weight of the record band-violation term. |
deficitWeight |
Finite positive weight of the suite-mean deficit term. |
Details
Duplicate RecordID/Tn/kind keys are errors.
Alignment retains target periods present in the final curves and requires
at least two records with a finite spectral matrix.
The solver uses absolute and relative tolerances of 1e-8,
a maximum of 200000 iterations and polishing; the returned status is
solved or solved inaccurate, and other statuses are errors.
The stage RMSE is relative to Sa.mean; PGA ratio is NA
when the aligned periods lack zero, and rcond is NA
when its matrix calculation fails.
The function calculates in memory and performs no file access.
Value
A list with scale and stage data.tables.
scale contains RecordID and scaleFactor in the
requested record order after alignment.
stage contains one row labelled B, the osqp method
and solver status, objective weights, relative RMSE, PGA ratio, band
violation and scale statistics, and matrix diagnostics
equations, records, rankSVD, cond2 and rcond.
See Also
fitModalFactor(), assessCompatibility()
Examples
Target <- data.table::data.table(Tn = c(0, 1), Sa.low = 0.50 * 9806.65,
Sa.mean = 0.84 * 9806.65, Sa.high = 0.95 * 9806.65)
PSA <- data.table::data.table(RecordID = rep(c("R1", "R2"), each = 2),
kind = "final", Tn = c(0, 1, 0, 1), Sa = c(7000, 8500, 4000, 6000))
Fit <- fitRecordFactor(PSA, target = Target, records = c("R1", "R2"),
factorMin = 0.5, factorMax = 1.6, bandWeight = 2, deficitWeight = 1)
print(Fit$scale)
print(Fit$stage[, c("status", "RMSE", "pgaRatio", "insideFraction", "nAtMax")])
Lengthen wide response spectra
Description
Converts <ID>.<OCID> columns to canonical long spectra without
changing values, units or the supplied table.
Usage
lengthenPSW(PSW, by, ids = c("PSA", "PSV", "SD"))
Arguments
PSW |
Wide table with |
by |
Character vector of metadata columns to retain, or
|
ids |
Preferred order of spectral IDs. Other IDs remain after these; the argument orders rows without filtering quantities. |
Details
The first dot separates ID from OCID; additional dots remain part of OCID. Duplicate metadata/period keys are errors. A correctly shaped empty input retains the key columns and has no spectral rows. The projection uses no random numbers, files or session-option changes.
Value
A new data.table with by,OCID,Tn,ID,S, ordered by metadata,
component, preferred ID and period. NA values remain explicit rows.
See Also
widenPSL(), computeSpectraTSL()
Examples
PSW <- data.table::data.table(RecordID = "R1", Tn = 0.1, PSA.H1 = 1)
lengthenPSW(PSW, by = "RecordID")
Lengthen wide time-series columns
Description
Converts columns named <ID>.<OCID> into canonical samples without
signal processing, unit conversion, or mutation of the supplied table.
Usage
lengthenTSW(TSW, by, ids = c("AT", "VT", "DT"))
Arguments
TSW |
A table with |
by |
Character vector of metadata columns to retain; use
|
ids |
Preferred quantity order; quantities not listed are retained. |
Details
The first dot separates ID and OCID; additional dots in OCID remain intact. Duplicate metadata/time keys are errors. Tables carrying both t and ts are rejected. Sparse wide cells become explicit NA rows.
Value
A new data.table with columns by,OCID,ID,t,s, ordered by
metadata, component, preferred quantity and time. NA values remain NA.
Metadata and amplitudes retain their supplied units.
See Also
Examples
TSW <- data.table::data.table(RecordID = "R1", t = c(0, 0.01),
AT.H1 = c(1, 2), VT.H1 = c(0.1, 0.2))
lengthenTSW(TSW, by = "RecordID")
Map provider channels to canonical directions
Description
Classifies one three-component record as H1, H2 and UP while preserving provider channel identities in OCID. Optional rotation aligns the horizontal signals with their principal axes.
Usage
mapComponents(data, rotate, output = "long")
Arguments
data |
A long data.table with |
rotate |
Logical scalar selecting horizontal rotation. |
output |
Either |
Details
Classification requires three OCID values and one recognized vertical channel. Finite horizontal peaks provide the classification fallback when covariance is unavailable. Rotation requires at least two finite horizontal pairs. The input table remains unchanged.
Value
A long data.table with t, OCID, DIR, s, or a wide data.table
with t, H1, H2, UP. Both carry componentMap and rotate
attributes; rotated results also carry theta in radians. Returns
NULL when the record cannot be classified or rotated.
Examples
Time <- seq(0, 1, by = 0.01)
Record <- data.table::data.table(
t = rep(Time, 3), OCID = rep(c("HNE", "HNN", "HNZ"), each = length(Time)),
s = c(sin(2 * pi * 2 * Time), 0.5 * sin(2 * pi * 2 * Time + 0.3),
0.2 * sin(2 * pi * 5 * Time)))
Wide <- mapComponents(Record, rotate = FALSE, output = "wide")
head(Wide)
attr(Wide, "componentMap")
Rotated <- mapComponents(Record, rotate = TRUE)
attr(Rotated, "theta")
head(Rotated)
Match selected records and publish project products
Description
Composes modal shaping, record scaling and population summaries.
Usage
matchProject(file = file.path("gmsp", "match.json"), root = getwd())
Arguments
file |
Path to the JSON project contract, relative to root or absolute. |
root |
Existing project directory used to resolve relative paths. |
Details
The contract declares id, a source folder or processed base with an
explicit selection, target, shape, units, xi, fmax, kNyq, nTheta, signalControl
and imf.criterion. A database selection uses path.selection or an explicit
candidate.ownerID. imf.criterion accepts band or energyFraction, or exactly
list(rule = "target", action = "remove"). The target rule retains mode centers
in [1/max(Tn), fmax] Hz using positive periods of the actual target after
the Tn restriction and fmax from the contract. fmax must exceed 1/max(Tn).
metadata/criterion.json records the requested rule/action,
effective fMin/fMax in Hz, TnMax in seconds (null for explicit rules)
and origin target/explicit. Energy-fraction rules have null frequency limits.
imf.includeResidue defaults to TRUE: a present residue has coefficient one,
outside the modal optimization; final energy restoration includes it.
signalControl supplies the buildTSL controls required by
fitModalFactor. Upper modal and record-factor bounds accept the exact JSON
string "Inf"; other numeric controls require numbers. units.psa must match
the acceleration unit of units.target. Products use units.target.
summary.probabilities is optional; when absent mean.csv keeps Tn, Sa and
recordCount, the arithmetic mean that gmsp 0.8.0 wrote, and
intensitySummary.csv keeps OCID, IM, mean and recordCount.
When supplied, probabilities are finite, unique and within [0,1];
mean.csv adds q probability columns and intensitySummary.csv adds p and value.
Summaries use quantile type 7 without removing missing values; duplicate
population keys and nonfinite values are errors. The keys plot.audit and
plot.standard are ignored since gmsp 1.0.0 with a warning, because figures
are produced in the reports scaffold; no plot or audit folder is written.
override defaults to FALSE;
TRUE replaces known files while preserving foreign files. Failed records or
writes preserve their causes and signal incomplete publication. The working
directory is unchanged.
parallel is TRUE or FALSE and defaults to FALSE. A declared workers value is one positive integer, even when parallel is FALSE; other values of either key are usage errors. When workers is absent, it is the number of logical cores that parallel::detectCores reports. With parallel TRUE and more than one worker, records are fitted in up to workers concurrent R processes, never more than the selected records; otherwise they are fitted one after another in the calling R process.
In match/metrics.csv, status done marks a fitted record and status error a failed one, whose error column keeps its condition message and whose convergence and message are NA. For a fitted record, convergence and message retain the stats::optim result of the L-BFGS-B modal fit: convergence 0 is successful completion, 1 means that the iteration limit maxit was reached, and 51 and 52 are a warning and an error of L-BFGS-B explained by message. message is the optimizer text, such as NEW_X, or NA when the optimizer returns none. The modal fit is limited to one iteration (maxit = 1), so 1 is the expected code and does not indicate a failure. The convergence code does not change status.
Value
Invisible integer zero after publication of data, metadata and match products under path.out.
Matching with the band
Modal shaping uses squared relative error to Sa.mean and squared relative violations below Sa.low or above Sa.high, together with the modal-factor movement penalty. During record scaling, shape.bandWeight weights individual record band violations, while shape.deficitWeight weights the suite-mean deficit below Sa.mean. Both stages use the target band including zero (PGA). match/target.csv publishes Tn, Sa.low, Sa.mean and Sa.high in units.psa; metadata/runMatch.json copies the contract, including target.envelope.
Target envelope
target.envelope is a required JSON object with lower and upper fields,
for example {"lower": "0.50", "upper": "0.95"}.
Each bound and target.p select an exact p label in the target table:
"mean" or a decimal of the form 0.<digits> strictly between
0 and 1, such as "0.50". Percentages ("50", "50%")
and p prefixes ("p50") are rejected.
Numeric scalars are converted to text and must satisfy the same decimal
format and literal table match; "0.5" and "0.50" are different labels.
The lower, central and upper labels must be distinct; duplicate object keys
and target.envelope.ID are rejected. "mean" is valid for either bound
or target.p when its rows exist and satisfy the band checks.
lower, target.p and upper become Sa.low, Sa.mean and Sa.high respectively;
Sa.mean denotes the selected central curve even when target.p is a quantile.
The curves require identical Tn meshes containing zero (PGA) and positive
periods, with finite ordinates satisfying 0 < Sa.low <= Sa.mean <= Sa.high
at every retained period. Tn is in seconds.
Ordinates are read in target.units (default g) and converted to units.psa;
conversions between g and mm/s2 (or mm/s^2) are supported, and identical
units are retained.
See Also
fitModalFactor(), fitRecordFactor(), assessCompatibility()
Examples
Root <- tempfile("matchProject")
for (DIR in c("data", "source/data", "source/metadata")) {
dir.create(file.path(Root, DIR), recursive = TRUE)
}
Target <- data.table::CJ(ID = "MCE", siteID = "SITE", Vs30 = 800,
Tn = c(0, 0.01, 0.04, 1, 5, 10), p = c("0.50", "0.84", "0.95"))
Target$SaF <- as.numeric(Target$p)
saveRDS(Target, file.path(Root, "data", "MCETable.Rds"))
Keys <- data.table::data.table(RecordID = c("R1", "R2"), OwnerID = "A",
EventID = c("E1", "E2"), StationID = "S1")
Time <- seq(0, 4, by = 0.01)
Mode <- 3000 * sin(2 * pi * Time)
Residue <- 300 * sin(pi * Time)
Signal <- Mode + Residue
Velocity <- cumsum(Signal) * 0.01
Displacement <- cumsum(Velocity) * 0.01
# R2 repeats the histories of R1 at 60 percent of their amplitude.
Rows <- rep(seq_len(nrow(Keys)), each = length(Time))
Amplitude <- c(1, 0.6)[Rows]
data.table::fwrite(data.table::data.table(Keys[Rows], t = Time,
AT.H1 = Amplitude * Signal, AT.H2 = 0.5 * Amplitude * Signal,
AT.UP = 0.3 * Amplitude * Signal, VT.H1 = Amplitude * Velocity,
VT.H2 = 0.5 * Amplitude * Velocity, VT.UP = 0.3 * Amplitude * Velocity,
DT.H1 = Amplitude * Displacement, DT.H2 = 0.5 * Amplitude * Displacement,
DT.UP = 0.3 * Amplitude * Displacement),
file.path(Root, "source", "data", "TSW.csv"))
data.table::fwrite(data.table::data.table(Keys[Rows], OCID = "H1", t = Time,
signal = Amplitude * Signal, IMF1 = Amplitude * Mode,
residue = Amplitude * Residue), file.path(Root, "source", "data", "IMF.csv"))
data.table::fwrite(data.table::data.table(Keys, status = "done"),
file.path(Root, "source", "data", "manifest.csv"))
data.table::fwrite(Keys, file.path(Root, "source", "metadata", "MasterIndex.csv"))
data.table::fwrite(data.table::data.table(Keys, OCID = "H1"),
file.path(Root, "source", "metadata", "OCIDMAP.csv"))
jsonlite::write_json(list(id = "demo",
path = list(source = "source", out = "out", data = "data"),
target = list(demand = "MCE", siteID = "SITE", Vs30 = 800, p = "0.84",
value = "SaF", units = "g", envelope = list(lower = "0.50", upper = "0.95")),
Tn = list(min = 0.04, max = 5),
shape = list(modalFactor = list(min = 0.001, max = "Inf"),
recordFactor = list(min = 0.5, max = 1.6), bandWeight = 2, deficitWeight = 1),
units = list(source = "mm", target = "mm", psa = "mm/s2"),
imf = list(criterion = list(rule = "target", action = "remove")),
signalControl = list(windowLength = 128, overlap = 75, astop0 = 0.001,
apass0 = 0.001, astopLP = 0.001, apassLP = 0.98, includeWarnings = FALSE),
xi = 0.05, fmax = 25, kNyq = 4, nTheta = 180, parallel = FALSE),
file.path(Root, "match.json"), auto_unbox = TRUE)
matchProject(file = "match.json", root = Root)
list.files(file.path(Root, "out", "match"))
data.table::fread(file.path(Root, "out", "match", "scale.csv"))
unlink(Root, recursive = TRUE)
Measure intensities from time histories
Description
Computes scalar intensity measures for each record, component and signal domain after conversion to the requested length basis.
Usage
measureIntensitiesTSL(TSL, by, unitsSource, unitsTarget)
Arguments
TSL |
A table with columns |
by |
Character vector of record metadata columns; |
unitsSource, unitsTarget |
Required source and target length bases:
|
Details
Each series is ordered by t and requires at least two finite numeric
samples with unique times. Duplicate by,OCID,ID,t keys, missing AT,
incomplete domain sets and unsupported units are errors.
Arias intensity and cumulative absolute velocity use mean-step rectangular sums including the first sample. CAV5 includes samples with absolute acceleration at least 0.05 times standard gravity. Durations use the first crossings without interpolation: D0595 uses 0.05 and 0.95, D2080 uses 0.20 and 0.80, and D0575 uses 0.05 and 0.75. Zero signals return zero duration. Zero-crossing counts include adjacent zero samples when the series has more than two samples. Dmax is the last time, including a nonzero time origin. The first FFT coefficient is assigned one frequency step, and mean periods use the 0.1–25 Hz band; zero signals return zero mean period. PDI retains Inf or NaN when its zero-crossing denominator is zero.
The input is copied. The function reads or writes no files, uses no random numbers and changes no session options.
Value
A new data.table with columns by,OCID,ID,IM,value,units.
Rows follow quantity order AT, VT, DT and the measure order below;
record/component groups retain their first-occurrence order within each
measure. Dimensional values use unitsTarget; the units column
identifies the units of each measure.
Measures
AT returns AI, AIu, AId, PGA, ARMS, AZC, ATo, ATn, D0595, D2080, D0575, TmA, CAV, CAV5, NP, dt, Fs, Dmax, EPI and PDI. VT returns PGV, VRMS, VZC, VTo, VTn and TmV. DT returns PGD, DRMS, DZC, DTo, DTn and TmD.
See Also
accumulateIntensityTSL(), widenIML()
Examples
t <- seq(0, 1, by = 0.01)
TSL <- data.table::rbindlist(list(
data.table::data.table(t = t, s = sin(2 * pi * t), ID = "AT", OCID = "H1"),
data.table::data.table(t = t, s = cos(2 * pi * t), ID = "VT", OCID = "H1"),
data.table::data.table(t = t, s = sin(pi * t), ID = "DT", OCID = "H1")))
measureIntensitiesTSL(TSL, by = character(),
unitsSource = "mm", unitsTarget = "mm")
Normalize all quantities by a reference peak
Description
Applies one factor per record and component, based on the peak of AT, VT or DT. The input table is preserved, including its row order.
Usage
normalizeTSL(TSL, by, reference)
Arguments
TSL |
Canonical long table with |
by |
Character vector of record metadata columns, or
|
reference |
Reference measure: exactly |
Details
A missing reference, nonfinite reference sample or nonpositive reference peak is an error. Samples are not omitted to compute a peak. All quantities in the group are scaled, including additional IDs.
Value
A new data.table with the same columns and rows, whose s values
are divided by the reference peak in each by,OCID group.
No metadata unit is reinterpreted. Other quantities use the same factor;
their own peaks need not equal one.
Examples
t <- seq(0, 1, by = 0.01)
TSL <- data.table::rbindlist(list(
data.table::data.table(t = t, s = 2 * sin(2 * pi * t), ID = "AT", OCID = "H1"),
data.table::data.table(t = t, s = cos(2 * pi * t), ID = "VT", OCID = "H1"),
data.table::data.table(t = t, s = sin(pi * t), ID = "DT", OCID = "H1")))
normalizeTSL(TSL, by = character(), reference = "PGA")
Parse provider files for one record
Description
Reads unique FileID entries under
path/OwnerID/EventID/StationID/raw.owner/ using the owner's format.
Usage
parseRecord(record, path)
Arguments
record |
A data.table with OwnerID, EventID, StationID and FileID. OwnerID, EventID and StationID identify one station record. |
path |
Path to the records root. |
Details
Missing keys, NA keys, multiple records and owners without a format raise errors before file reading. Duplicate FileID entries are read once. This operation does not add ID, convert amplitudes or write files.
Value
A long data.table with t, OCID, s in native units.
Examples
Root <- tempfile("parseRecord")
Station <- file.path(Root, "NGAW", "E1", "S1", "raw.owner")
dir.create(Station, recursive = TRUE)
Samples <- c(HNE = "0.01 0.03 -0.02 0.01", HNN = "0.02 -0.01 0.01 0",
HNZ = "0 0.01 -0.01 0")
for (Channel in names(Samples)) {
writeLines(c("header", paste0("Event, date, station, ", Channel), "units",
"NPTS= 4, DT= 0.01 SEC", Samples[[Channel]]),
file.path(Station, paste0(Channel, ".AT2")))
}
Record <- data.table::data.table(OwnerID = "NGAW", EventID = "E1",
StationID = "S1", FileID = paste0(names(Samples), ".AT2"))
parseRecord(Record, path = Root)
unlink(Root, recursive = TRUE)
Process selected project records
Description
Reads a project JSON contract and publishes record products, process tables, a signed processing recipe and execution evidence.
Usage
processProject(file = file.path("gmsp", "process.json"), root = getwd())
Arguments
file |
Path to the JSON contract, relative to root or absolute. The default is gmsp/process.json. |
root |
Existing project directory used to resolve relative paths. The default is the caller's working directory. |
Details
The contract requires processID, ordered stages, path.selection, path.stage for execution evidence, and roots for records, index and process. path.database can supply these roots; explicit paths take precedence. Scientific controls are explicit in each stage section.
The stages are gmsp, trim, imf, imfTS and psa. Raw processing produces TSW and IMW; trim replaces these products within the same run, and psa writes PSW. imf writes IMF and IMFF through decomposeRecords and the xemd mode metrics. imfTS reads IMF, selects by its explicit criterion, reintegrates through reconstructRecords and writes TSW and IMW.
imf.method accepts vmd, eemd or a native xemd decomposition name. vmd requires k, alpha, tau, DC, init, tolerance and maxIterations in imf; eemd requires k, noise.amp, trials and sifting. Native methods take their controls in imf.control. Numeric JSON arrays become numeric vectors. imfTS requires criterion, fmax, kNyq, unitsTarget, windowLength, overlap, astop0, apass0, astopLP and apassLP. criterion uses band or energyFraction with an explicit action; rule target is resolved only by match and is rejected here. Removal by mode name is rejected. includeResidue defaults to TRUE. Optional signal controls follow reconstructRecords.
Stochastic imf requires imf.seed, parallel FALSE and workers 1 explicitly. The process sorts the record keys and calls set.seed once for a nonempty batch of new records. The caller's resulting random state is retained. A modal JSON file beside the execution evidence records the seed, RNGkind, states before and after processing, executed and skipped records, effective controls and xemd version. Reproducibility is limited to the same environment, seed and executed order.
Append compares the recipe identity before processing records and skips complete records already committed under that identity. Writer locks and metadata transactions protect publication. An incomplete rollback retains its recovery transaction and record products.
Input errors, processing failures and partial publication raise conditions instead of returning 0. Failures retain their causes; partial publication identifies the products or transaction retained for recovery. The operation preserves the caller's working directory and session options.
Value
Invisible integer 0 after complete publication.
Examples
Root <- tempfile("processProject")
Raw <- file.path(Root, "database", "records", "A", "E1", "S1", "raw")
dir.create(Raw, recursive = TRUE)
Time <- seq(0, 10, by = 0.01)
Envelope <- sin(pi * Time / max(Time))^2
data.table::fwrite(data.table::data.table(
HNE = 1200 * Envelope * sin(2 * pi * 1.5 * Time),
HNN = 800 * Envelope * sin(2 * pi * 2.5 * Time + 0.4),
HNZ = 400 * Envelope * sin(2 * pi * 4 * Time)), file.path(Raw, "AT.R1.csv"))
jsonlite::write_json(list(RecordID = "R1", OwnerID = "A", EventID = "E1",
StationID = "S1", dt = 0.01), file.path(Raw, "AT.R1.json"), auto_unbox = TRUE)
data.table::fwrite(data.table::data.table(ProcessID = "raw", RecordID = "R1",
OwnerID = "A", EventID = "E1", StationID = "S1"), file.path(Root, "selection.csv"))
# The gmsp stage spells its edge stop amplitude Astop0.
jsonlite::write_json(list(processID = "TEST", stages = "gmsp",
parallel = FALSE, workers = 1,
path = list(database = "database", selection = "selection.csv", stage = "stage"),
gmsp = list(fmax = 25, kNyq = 4, flatZeros = FALSE, trimZeros = FALSE,
Astop0 = 0.001, unitsSource = "mm", unitsTarget = "mm", windowLength = 128,
overlap = 75, astopLP = 0.001, apass0 = 0.001, apassLP = 0.98)),
file.path(Root, "process.json"), auto_unbox = TRUE)
processProject(file = "process.json", root = Root)
list.files(file.path(Root, "database", "process", "TEST"))
Intensity <- data.table::fread(file.path(Root, "database", "process", "TEST",
"IntensityTable.csv"))
print(Intensity[, c("RecordID", "OCID", "PGA", "AI")])
unlink(Root, recursive = TRUE)
Rank a processed candidate pool
Description
Scores candidate spectra against a target band and writes a selection.
Usage
rankProject(file = file.path("gmsp", "match.json"), root = getwd())
Arguments
file |
Path to the JSON project contract, relative to root or absolute. |
root |
Existing project directory used to resolve relative paths. |
Details
stage0.N is an integer of at least two. The contract declares a
processed base, target, xi, units.psa and candidate.ownerID or a candidate.pool
with complete record keys. An explicit owner selector may be filtered by a pool.
candidate.oneRecordPerEvent defaults to FALSE; when TRUE, the best-ranked
record of each earthquake is kept, with the event identity of
selectProject() read from the MasterIndex. Declared PSW is preferred;
otherwise spectra are calculated from TSW. Checkpoint reuse requires identical
resolved inputs and recipe, including oneRecordPerEvent, and an unchanged
checkpoint file. Missing or mismatched identity causes a resumption error.
parallel and workers are not read: ranking runs in the calling R process,
and both keys enter the checkpoint identity with the rest of the contract.
Invalid inputs and partial publication cause errors. The working directory is unchanged.
Value
Invisible integer zero after publication of stage0.psa.csv, stage0.identity.json, stage0.spectral.csv and the file at path.selection.
Target envelope
target.envelope is a required JSON object with lower and upper fields,
for example {"lower": "0.50", "upper": "0.95"}.
Each bound and target.p select an exact p label in the target table:
"mean" or a decimal of the form 0.<digits> strictly between
0 and 1, such as "0.50". Percentages ("50", "50%")
and p prefixes ("p50") are rejected.
Numeric scalars are converted to text and must satisfy the same decimal
format and literal table match; "0.5" and "0.50" are different labels.
The lower, central and upper labels must be distinct; duplicate object keys
and target.envelope.ID are rejected. "mean" is valid for either bound
or target.p when its rows exist and satisfy the band checks.
lower, target.p and upper become Sa.low, Sa.mean and Sa.high respectively;
Sa.mean denotes the selected central curve even when target.p is a quantile.
The curves require identical Tn meshes containing zero (PGA) and positive
periods, with finite ordinates satisfying 0 < Sa.low <= Sa.mean <= Sa.high
at every retained period. Tn is in seconds.
Ordinates are read in target.units (default g) and converted to units.psa;
conversions between g and mm/s2 (or mm/s^2) are supported, and identical
units are retained.
Ranking with the band
At positive target periods, Sa.low and Sa.high define insideFraction and relative band violations. Candidates are ordered by bandRMSE, q90Violation and relaxedRMSE, with RecordID breaking ties. relaxedRMSE compares with Sa.mean and downweights values inside the band. stage0.spectral.csv records these scores before publication of the selection at path.selection.
Event magnitude
Before candidate.filter is applied, the EventMagnitude of the MasterIndex
is transformed as in selectProject(): an Mw published by the index is
kept, otherwise one published by the owner is taken; otherwise an Ms in
any letter case becomes 0.67 Ms + 2.13, the ISC-GEM catalogue
relation of Storchak et al. (2013) as reproduced by
Villalón-Semanat and Palau-Clares (2018, equation 10),
published for Ms <= 6.47 and extrapolated to every larger Ms.
An mb in any letter case without a published Mw becomes 0.85 mb + 1.03 for
3.5 <= mb & mb <= 6.2, the global empirical relation of
Scordilis (2006, equation 22); outside that interval Mw = mb.
An ML without a published Mw is taken as Mw by identity. Magnitude types are compared in any
letter case. Md and other or empty types keep their magnitude.
A candidate.filter range on EventMagnitude and the Mw column of
stage0.spectral.csv use the resulting magnitude. The MasterIndex file
is unchanged and no column is added.
References
Villalón-Semanat, M. and Palau-Clares, R. (2018). Relaciones empíricas entre las magnitudes mb/Ms, Ms/Mw y mb/Mc para el área de Cuba, Jamaica y La Española. Minería y Geología, 34(2), 167-176.
Scordilis, E. M. (2006). Empirical Global Relations Converting MS and mb to Moment Magnitude. Journal of Seismology, 10(2), 225-236. doi:10.1007/s10950-006-9012-4.
See Also
selectProject(), matchProject()
Examples
Root <- tempfile("rankProject")
Process <- file.path(Root, "database", "process", "TEST")
dir.create(Process, recursive = TRUE)
dir.create(file.path(Root, "data"))
Keys <- data.table::data.table(ProcessID = "TEST", RecordID = c("R1", "R2", "R3"),
OwnerID = c("A", "B", "A"), EventID = c("E1", "E2", "E3"), StationID = "S1")
data.table::fwrite(data.table::data.table(Keys, EventName = "First",
EventMagnitude = 6, Repi = 10), file.path(Process, "MasterIndex.csv"))
data.table::fwrite(data.table::data.table(RecordID = Keys$RecordID, OCID = "H1",
PGA = 100, AI = 10), file.path(Process, "IntensityTable.csv"))
data.table::fwrite(data.table::data.table(Keys[rep(seq_len(nrow(Keys)), each = 2)],
Tn = rep(c(0.5, 2), nrow(Keys)),
PSA.H1 = rep(c(0.84, 0.99, 0.40), each = 2) * 9806.65),
file.path(Process, "PSW.csv"))
jsonlite::write_json(list(processID = "TEST", output = list(record = "PSW",
table = c("MasterIndex", "IntensityTable", "PSW"))),
file.path(Process, "process.json"), auto_unbox = TRUE)
Target <- data.table::CJ(ID = "MCE", siteID = "SITE", Vs30 = 800, Tn = c(0, 1),
p = c("0.50", "0.84", "0.95"))
Target$SaF <- as.numeric(Target$p)
saveRDS(Target, file.path(Root, "data", "MCETable.Rds"))
jsonlite::write_json(list(processID = "TEST", xi = 0.05, units = list(psa = "mm/s2"),
stage0 = list(N = 2),
path = list(database = "database", data = "data", selection = "rank/selection.csv"),
candidate = list(ownerID = c("A", "B")),
target = list(demand = "MCE", siteID = "SITE", Vs30 = 800, p = "0.84",
value = "SaF", units = "g", envelope = list(lower = "0.50", upper = "0.95"))),
file.path(Root, "match.json"), auto_unbox = TRUE)
rankProject(file = "match.json", root = Root)
Scores <- data.table::fread(file.path(Root, "rank", "stage0.spectral.csv"))
print(Scores[, c("RecordID", "rank.band", "insideFraction", "bandRMSE")])
data.table::fread(file.path(Root, "rank", "selection.csv"))
unlink(Root, recursive = TRUE)
Read a provider signal file
Description
Returns provider channels and native amplitudes without unit conversion. Time is in seconds; TWO_COL preserves its time column and the other formats construct time from zero using the header sampling interval.
Usage
readProviderFile(file, format)
Arguments
file |
Path to one provider file. |
format |
One of AT2, TWO_COL, TRA, TRZ, TRB, TRC, ACA, ACB, LIS, V2, V2A or ISEE. V2 and ISEE variants are recognized within the format. |
Details
Unknown formats, unreadable files and invalid required headers raise errors with file and format context. Files are read without writes.
Value
A data.table with columns t, OCID, s. An NPTS block with
insufficient samples or NA within its declared samples returns NULL;
multi-block readers omit such blocks. ISEE returns T, V and L velocities
in mm/s.
Examples
Root <- tempfile("readProviderFile")
dir.create(Root)
File <- file.path(Root, "record.AT2")
writeLines(c("header", "Event, date, station, H1", "units",
"NPTS= 4, DT= 0.01 SEC", "1.0 2.0 3.0 4.0"), File)
readProviderFile(File, format = "AT2")
unlink(Root, recursive = TRUE)
Read raw records as long time histories
Description
Reads the requested raw CSV and JSON pairs and reconstructs time from zero using the sidecar sampling interval, without converting amplitudes.
Usage
readRecordTSL(records, path, ID)
Arguments
records |
Table with RecordID, OwnerID, EventID and StationID keys. |
path |
Records root containing the per-station raw folders. |
ID |
Required quantity AT, VT or DT, selecting the file prefix. |
Details
A missing requested pair, a nonpositive or nonfinite sampling interval, or a sidecar key contradicting the selection causes an error with the record and path. The supplied table is not modified.
Value
A new data.table with columns RecordID, OwnerID, EventID, StationID, OCID, ID, t and s, ordered by those keys and t. OCID retains the provider channel names. Time t is in seconds.
Examples
Root <- tempfile("readRecordTSL")
Raw <- file.path(Root, "AAA", "E1", "S1", "raw")
dir.create(Raw, recursive = TRUE)
data.table::fwrite(data.table::data.table(H1 = c(1, 2), H2 = c(0, 1)),
file.path(Raw, "AT.R1.csv"))
jsonlite::write_json(list(dt = 0.01), file.path(Raw, "AT.R1.json"), auto_unbox = TRUE)
Keys <- data.table::data.table(RecordID = "R1", OwnerID = "AAA",
EventID = "E1", StationID = "S1")
readRecordTSL(Keys, path = Root, ID = "AT")
unlink(Root, recursive = TRUE)
Reconstruct acceleration records from selected modes
Description
Measures and selects modes through xemd, reconstructs acceleration, and reintegrates it with buildTSL using isRaw = FALSE.
Usage
reconstructRecords(
decomposition,
criterion,
by,
signalControl,
includeResidue = TRUE
)
Arguments
decomposition |
Native list returned by decomposeRecords, containing signal and modes tables with ID AT, OCID, t in seconds, s and metadata. Samples use the length basis declared by signalControl$unitsTarget. An optional residue or fitResidual supplies the remainder; both together are an error. |
criterion |
Named list with exactly rule, action and the rule fields. Rule "band" requires finite fMin and fMax in Hz with 0 <= fMin <= fMax; "energyFraction" requires finite minimum >= 0. Action is "keep" or "remove"; selection by mode index is not admitted. |
by |
Explicit character vector of metadata columns identifying a record; character() declares one record without grouping metadata. Metadata must be constant within each record/component/quantity series. Only the metadata selected by by is retained in the returned TSL. |
signalControl |
Named list requiring unitsTarget, fmax, windowLength, overlap, astop0, apass0, astopLP and apassLP, with the units and conditions of buildTSL. Optional kNyq, flatZeros, trimZeros, removeMean, forceRegularization and includeWarnings retain their buildTSL defaults. Duplicate or other fields are errors; Units metadata, when present, must agree with unitsTarget. |
includeResidue |
Logical scalar, TRUE by default, including residue or fitResidual when present; an absent remainder contributes nothing. |
Details
Selection applies separately by OCID and retains native mode identities; the closed band compares frequency without bandwidth. A zero-energy mode has no frequency and is outside a frequency band. Reconstruction sums retained modes and the requested remainder before reintegration; meanNoise is not added again. Zero reconstructed acceleration energy is an error before buildTSL. Reintegration can taper, resample or remove means according to the supplied signal controls, so its histories need not equal the modal sum.
Invalid data or controls cause errors; dependency conditions retain their original classes, cause and group when supplied. Inputs are preserved; the operation reads or writes no files and uses no random numbers.
Value
A list with TSL, the reintegrated AT/VT/DT table; metrics, the freshly measured native mode metrics; and selection, the native decision table for that decomposition.
See Also
decomposeRecords(), buildTSL(), xemd::selectModesTSL(),
xemd::reconstructTSL()
Examples
Time <- seq(0, 9, length.out = 1000)
TSL <- data.table::data.table(RecordID = "R1", OCID = "H1", ID = "AT", t = Time,
s = sin(pi * Time) + sin(2 * pi * Time) + sin(6 * pi * Time) + 0.5 * Time,
Units = "mm")
Decomposition <- decomposeRecords(TSL, method = "vmd",
control = list(k = 3, alpha = 2000, tau = 0.5, DC = FALSE, init = 0,
tolerance = 1e-6, maxIterations = 98),
by = "RecordID")
Control <- list(unitsTarget = "mm", fmax = 25, kNyq = 4, windowLength = 128,
overlap = 75, astop0 = 1e-3, apass0 = 1e-3, astopLP = 1e-3,
apassLP = 0.98, includeWarnings = FALSE)
Reconstruction <- reconstructRecords(Decomposition,
criterion = list(rule = "band", fMin = 2, fMax = 15, action = "keep"),
by = "RecordID", signalControl = Control)
print(Reconstruction$selection)
head(Reconstruction$TSL)
unique(Reconstruction$TSL$ID)
Select records from a project contract
Description
Filters index metadata and writes the selected records and candidate pool.
Usage
selectProject(file = file.path("gmsp", "select.json"), root = getwd())
Arguments
file |
Path to the JSON project contract, relative to root or absolute. |
root |
Existing project directory used to resolve relative paths. |
Details
owners, path.selection and index paths are required. processID defaults to raw, requireIMF to FALSE and oneRecordPerEvent to TRUE. PGA criteria require units.PGA. A target PGA can be derived from path.matchConfig and explicit positive record-factor bounds. A selection directory containing foreign entries is rejected before replacement. Missing contracts, invalid criteria and partial publication cause errors. The working directory is unchanged.
Value
Invisible integer zero after publication of selection.csv, candidates.csv, selection.json and summary.json under path.selection.
One record per event
Records belong to the same earthquake when their EventID.USGS is equal; legacy processed indexes name that column usgsEventId. A record without it is identified by its EventID. With oneRecordPerEvent TRUE, selection.csv keeps one record per earthquake, the one with the largest PGA; ties go to the larger StationID and then to the smaller RecordID. candidates.csv keeps every record that meets a criterion. The events count in summary.json uses the same identity.
Event magnitude
Before the criteria are applied, EventMagnitude takes a moment magnitude
where one is published or an Ms or mb is converted. When EventMagnitudeType
is mw, mwc, mww, mwr or mwb in any letter case, the magnitude and its type
are kept. Otherwise, when EventMagnitudeType.owner is one of those types,
EventMagnitude.owner is taken and the type becomes Mw. Otherwise an Ms in
any letter case becomes 0.67 Ms + 2.13 and its type becomes Mw.
This is the ISC-GEM catalogue relation of Storchak et al. (2013) as
reproduced by Villalón-Semanat and Palau-Clares (2018,
equation 10); it is published for Ms <= 6.47, and the same line is
extrapolated to every larger Ms.
An mb in any letter case without a published Mw becomes 0.85 mb + 1.03 for
3.5 <= mb & mb <= 6.2, the global empirical relation of
Scordilis (2006, equation 22). Outside that interval its value is kept,
so that Mw = mb; the type becomes Mw in both cases.
An ML without a published Mw keeps its value and takes the type Mw, an identity
meant for the moderate range. Md and other or empty types keep their
magnitude and type. The EventMagnitude and EventMagnitudeType criteria and
the published tables use the resulting values. The source values remain
in the .owner and .USGS columns of the index (and .ISC where present).
References
Villalón-Semanat, M. and Palau-Clares, R. (2018). Relaciones empíricas entre las magnitudes mb/Ms, Ms/Mw y mb/Mc para el área de Cuba, Jamaica y La Española. Minería y Geología, 34(2), 167-176.
Scordilis, E. M. (2006). Empirical Global Relations Converting MS and mb to Moment Magnitude. Journal of Seismology, 10(2), 225-236. doi:10.1007/s10950-006-9012-4.
See Also
Examples
Root <- tempfile("selectProject")
dir.create(file.path(Root, "database", "index"), recursive = TRUE)
dir.create(file.path(Root, "database", "process", "TEST"), recursive = TRUE)
Index <- data.table::data.table(ProcessID = "TEST", RecordID = c("001", "002", "003"),
OwnerID = "A", EventID = c("2020A", "2020A", "2021B"),
StationID = c("01", "02", "03"), DIR = "H1", OCID = "H1",
PGA = c(4903.325, 4903.325, 7354.9875))
data.table::fwrite(Index, file.path(Root, "database", "process", "TEST",
"MasterIndex.csv"))
jsonlite::write_json(list(processID = "TEST", owners = "A", oneRecordPerEvent = TRUE,
path = list(index = "database/index", selection = "selection")),
file.path(Root, "select.json"), auto_unbox = TRUE)
selectProject(file = "select.json", root = Root)
list.files(file.path(Root, "selection"))
data.table::fread(file.path(Root, "selection", "selection.csv"),
colClasses = "character")
unlink(Root, recursive = TRUE)
Select record identities
Description
Intersects identity filters and returns unique record keys without modifying the supplied table.
Usage
selectRecords(
data,
recordID = NULL,
eventID = NULL,
stationID = NULL,
ownerID = NULL
)
Arguments
data |
Table containing RecordID, OwnerID, EventID and StationID. |
recordID, eventID, stationID, ownerID |
Identity vectors for the corresponding columns. NULL leaves a dimension unrestricted; an empty vector selects zero rows. |
Details
Duplicate key rows are collapsed. With every filter NULL, the result contains the unique keys of the supplied table. Missing required columns are input errors. The operation performs no file access.
Value
A data.table with RecordID, OwnerID, EventID and StationID, in that column order, sorted by OwnerID, EventID and StationID.
See Also
readRecordTSL(), writeSelection()
Examples
Records <- data.table::data.table(RecordID = c("R1", "R2", "R3"), OwnerID = "AAA",
EventID = c("E1", "E1", "E2"), StationID = c("S1", "S2", "S1"))
selectRecords(Records, eventID = "E1")
selectRecords(Records, stationID = "S1", ownerID = "AAA")
Widen long intensity measures
Description
Projects intensity measures to one row per record and component, with one column for each measure. Values and units are preserved without conversion.
Usage
widenIML(IML, by)
Arguments
IML |
A table with columns |
by |
Character vector of record metadata columns; |
Details
Keys by,OCID,IM must be unique; duplicate or contradictory measure
rows cause an error without aggregation. Absent ID or units fields are
omitted from the attribute. Metadata excluded by by are dropped.
CSV serialization contains the value columns; the measureMetadata
attribute remains an in-memory representation of domains and units.
The input is copied. The function reads or writes no files, uses no random numbers and changes no session options.
Value
A new data.table with columns by,OCID,<IM>, ordered by
metadata and component. Measure columns follow their first occurrence
in IML; missing combinations and supplied NA values remain missing.
The tabular attribute measureMetadata retains
by,OCID,IM and the available ID,units fields.
A correctly shaped empty input returns the row-key columns with zero
rows and no measure columns.
See Also
Examples
IML <- data.table::data.table(
RecordID = "R1", OCID = "H1", ID = "AT", IM = c("PGA", "CAV"),
value = c(500, 120), units = c("mm /s2", "mm /s"))
IMW <- widenIML(IML, by = "RecordID")
attr(IMW, "measureMetadata")
Widen canonical response spectra
Description
Projects spectra to columns named <ID>.<OCID> without changing
values or units. The input table is preserved.
Usage
widenPSL(PSL, by)
Arguments
PSL |
Long table with |
by |
Character vector of metadata columns forming row keys, or
|
Details
Duplicate by,Tn,ID,OCID keys are errors; values are not
aggregated. Missing combinations become NA. A correctly shaped empty
input returns its key columns with no spectra columns. The projection
uses no random numbers, files or session-option changes.
Value
A new data.table ordered by by,Tn. These key columns precede
the spectra columns, ordered by component with H1, H2, UP, D50 and D100
first, and by ID with PSA, PSV and SD first within each component.
Other components and IDs remain after the preferred values.
See Also
lengthenPSW(), computeSpectraTSL()
Examples
PSL <- data.table::data.table(RecordID = "R1", OCID = "H1",
Tn = 0.1, ID = "PSA", S = 1)
widenPSL(PSL, by = "RecordID")
Widen a canonical long time-series table
Description
Projects samples to columns named <ID>.<OCID>. It performs no
signal processing or unit conversion and does not modify its input.
Usage
widenTSL(TSL, by, ids = c("AT", "VT", "DT"))
Arguments
TSL |
A table with |
by |
Character vector of metadata columns identifying a record.
Use |
ids |
Preferred order of quantity identifiers. Other identifiers remain after these; this argument never filters quantities. |
Details
Duplicate by,t,ID,OCID keys are errors. A dense input with
nonempty identifiers and no dots in ID supports a lossless value round
trip. The first dot separates ID from OCID; further dots belong to OCID.
Sparse input acquires explicit NA rows on conversion back.
Value
A new data.table ordered by by,t, with those columns first
and one column per quantity/component. Missing combinations become NA.
Values and unit-bearing metadata selected in by are preserved.
See Also
Examples
TSL <- data.table::data.table(
RecordID = "R1", OCID = "H1", ID = rep(c("AT", "VT"), each = 2),
t = rep(c(0, 0.01), 2), s = c(1, 2, 0.1, 0.2))
widenTSL(TSL, by = "RecordID")
Write a station-folder selection
Description
Writes unique station-folder keys to CSV and a JSON summary.
Usage
writeSelection(data, name, path)
Arguments
data |
Table containing OwnerID, EventID and StationID. |
name |
Nonempty selection name used as the output filename stem. |
path |
Nonempty destination directory, created recursively if needed. |
Details
The files are named from name with .csv and .json suffixes. Existing files at these paths are overwritten. The JSON fields are name, dateUTC, nHits and hitsPerOwner; dateUTC uses UTC to the second. An empty selection has nHits zero. RecordID is not part of these keys. A JSON failure after CSV publication raises modulePartialPublication with the original condition, partial result and affected paths; the CSV remains. Completion signals a moduleNote condition. Missing required columns and invalid name/path arguments are input errors.
Value
Invisibly, a data.table with OwnerID, EventID and StationID, sorted by these keys and without duplicate rows.
See Also
Examples
Root <- tempfile("writeSelection")
Records <- data.table::data.table(OwnerID = "AAA", EventID = c("E1", "E1", "E2"),
StationID = c("S1", "S2", "S1"))
Selection <- writeSelection(Records, name = "demo", path = Root)
print(Selection)
list.files(Root)
str(jsonlite::read_json(file.path(Root, "demo.json")))
unlink(Root, recursive = TRUE)