Nothing
# detectors.R:
# R side interface to feature detectors. These are not specific to the
# spacing module; they can be used for any data.
#
# c 2024-2026 Greg Kreider, Primordial Machine Vision Systems, Inc.
## To Do:
# -
#
##### Public Interface
# Finds runs in data x, with fuzzy relative comparison where the difference
# from all points within the run to its start (not chaining along) is
# within the fraction feps of their average, ie. |(x2-x1)/((x1+x2)/2)| < feps.
# If feps is 0 then values must match exactly. Infinities match each other
# but not finite values and NA and NaN values are skipped. x can also be
# integer, logical, or string values in which only exact matches are supported
# (but still skipping NAs, unlike rle). Returns a general vector with elements
# $runs lengths of fuzzy runs, length of x, 0 if no run starts there
# $nskip number of skipped elements
# $stats ['nrun'] number of runs, ['maxrun'] longest run
# The runs and nskip vectors are set up to scan along the original data.
# i <- if (0 == r$runs[1]) { r$nskip[1] + 1 } else { 1 }
# i <- i + r$runs[i] + r$nskip[i]
# Use runs.as.rle to convert the result to an rle encoding.
# Typical values are 0.001 for feps.
find.runs <- function(x, feps) {
if (!is.vector(x)) {
x <- as.vector(x)
}
if (0 == length(x)) {
stop("vector has no data")
}
.Call("C_find_runs", x, feps, PACKAGE="Dimodal")
}
# Find local minima and maxima in data x, eliminating small peaks if
# they are less than the fraction fht of the total range of the data or if
# the height to an adjacent minimum is less than the fraction frelht of their
# average value. Values within fhtie are treated as equal (a fuzzy run) and
# considered located in the middle of the mesa. x must be an integer or real
# vector. The support of a maximum is the range of points until their values
# drop to the fraction fhsupp of the peak height to that side, similar to FWHM
# where fhsupp would be 0.5. The range is NA for minima and one-sided peaks.
# Return a data frame assigned to class Dipeak with extrema in rows and columns
# $pos position of extremum in x
# $ismax TRUE if a maximum, FALSE if a minimum
# $valsd data at extremum standardized by stdev
# $lht peak height to left minimum, NA at minimum or first peak
# $rht peak height to right minimum, NA at minimum or last peak
# $lminID position of minimum to left, NA if first/last or at minimum
# $rminID position of minimum to right, NA if first/last or at minimum
# $lsuppID first index of support range
# $rsuppID last index (incl.) of support range
# Typical values are 0.05 for fht, 0.15 for frelht, and 0.001 for fhtie.
# The data frame will be empty (0 rows) if the data do not support extrema:
# there are too few, or the values are constant, or are not finite.
find.peaks <- function(x, fht, frelht, fhtie, fhsupp) {
if (!is.vector(x)) {
x <- as.vector(x)
}
if (0 == length(x)) {
return(mockup.Dipeak())
}
pk <- .Call("C_find_peaks", x, fht, frelht, fhtie, fhsupp, PACKAGE="Dimodal")
df <- as.data.frame(pk)
class(df) <- c("Dipeak", class(df))
df
}
# Find local flats in data x, as defined by the fripple value as a fraction
# of the range of x centered at each point. Flats must have a length at least
# minlen (absolute) or a fraction fminlen as a fraction of the number of data
# points, whichever is larger. To each side of the seed flats may contain
# noutlier points outside the ripple spec, although the start or endpoint will
# always be in range. They may overlap. Data must be real or integer and
# non-finite values will be ignored. Returns a data frame with features in
# rows and columns
# $src point in x that seeded the flat, a unique identifier
# $stID starting index in x of each flat
# $endID ending index in x of each flat
# $len length of flat
# $srcval data value at src (center of flat height)
# $ht height of flat in x
# $htsd standardized height (by stdev) of flat
# Typical values are 0.05 for fripple, 30 for minlen, 0.05 for rellen, and
# 1 for noutlier.
find.flats <- function(x, fripple, minlen, fminlen, noutlier) {
# Final timing [ms] based on sub-set of asteroid axes, for Diw 150 window.
# This is using identify_flats_cover for both.
# # samples scan tree speed-up
# 1k 1 1 1x
# 5k 5 8 0.6x
# 10k 31 17 1.8x
# 50k 827 105 7.9x
# 100k 5250 294 17.9x
# 250k 33214 969 34.3x
# 500k 142768 1934 73.8x
# 750k 336697 4370 77.0x
if (!is.vector(x)) {
x <- as.vector(x)
}
if (sum(is.finite(x)) < 2) {
return(mockup.Diflat())
}
ft <- .Call("C_find_flats", x, fripple, minlen, fminlen, noutlier, 0L,
PACKAGE="Dimodal")
df <- as.data.frame(ft)
class(df) <- c("Diflat", class(df))
df
}
# Find intervals without a significant slope, inverting the interval spacing
# test used in the modehunt package. Data x must be real or integer, and
# non-finite values, including NA and NaN, will be removed; the indices will
# refer to the sorted raw data after removal. alpha is the significance
# level of the test, between 0 and 1, and correct, a boolean, if TRUE adjusts
# the test against short intervals. Returns a data frame with one row per
# section and columns
# $stID starting index in the sorted x of each section
# $endID ending index (incl.) of each section
# Typical values are 0.95 for alpha and TRUE for correct.
find.level.sections <- function(x, alpha, correct) {
if (!is.vector(x)) {
x <- as.vector(x)
}
# finmap will store the indices in the original data we're processing,
# which we need when mapping back from the level sections.
finmap <- which(is.finite(x))
x <- sort(x[finmap])
if (is.integer(x[1L])) {
x <- as.numeric(x)
}
if (length(x) < 3) {
stop("must have at least three points for level sections")
}
lvl <- .Call("C_find_level_sections", x, alpha, correct, PACKAGE="Dimodal")
data.frame( stID=finmap[lvl[["stID"]]], endID=finmap[lvl[["endID"]]] )
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.