Skip to content

Commit

Permalink
make .hzTests() -- simpler accessor method to key 'logic' of checkHzD…
Browse files Browse the repository at this point in the history
…epthLogic() #65
  • Loading branch information
brownag committed Jan 22, 2020
1 parent 9dcfb58 commit 8e508c2
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 40 deletions.
42 changes: 26 additions & 16 deletions R/checkHzDepthLogic.R
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,17 @@ checkHzDepthLogic <- function(x) {
ID.i <- h[[idn]][1]
.top <- h[[htb[1]]]
.bottom <- h[[htb[2]]]
.n <- length(.top)

# bottom depth < top depth?
test.1 <- any(.bottom < .top, na.rm = TRUE)

# bottom depth == top depth
test.2 <- any(.top == .bottom, na.rm = TRUE)

# NA depths
test.3 <- any(is.na(.top) | is.na(.bottom), na.rm = TRUE)

# bottom != next top
test.4 <- any(.bottom[-.n] != .top[-1], na.rm = TRUE)
# hzTests takes two numeric vectors and returns named logical
test <- .hzTests(.top, .bottom)

# pack into DF, 1 row per profile
res <- data.frame(
.id=ID.i,
depthLogic=test.1,
sameDepth=test.2,
missingDepth=test.3,
overlapOrGap=test.4,
depthLogic=test[1],
sameDepth=test[2],
missingDepth=test[3],
overlapOrGap=test[4],
stringsAsFactors = FALSE
)

Expand All @@ -57,3 +47,23 @@ checkHzDepthLogic <- function(x) {

return(res)
}

.hzTests <- function(top, bottom) {
n <- length(top)

# bottom depth < top depth?
test.1 <- any(bottom < top, na.rm = TRUE)

# bottom depth == top depth
test.2 <- any(top == bottom, na.rm = TRUE)

# NA depths
test.3 <- any(is.na(top) | is.na(bottom), na.rm = TRUE)

# bottom != next top
test.4 <- any(bottom[-n] != top[-1], na.rm = TRUE)

res <- as.logical(c(test.1, test.2, test.3, test.4))
names(res) <- c("depthLogic","sameDepth","missingDepth","overlapOrGap")
return(res)
}
46 changes: 22 additions & 24 deletions R/glom.R
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
# glom returns a "clod" of horizons that have a common attribute (currently just depth interval supported)

# returns unique index to all horizons occuring over the depth interval [z1, z2].
# z2 is optional, in which case a single horizon with depth range containing z1 is returned
# several wrapper functions around this for hzid

# a 'clod' is a ragged group of soil pedon horizons (each with distinctness, horizons boundaries)
# a clod references the original pedon data, it is not resampled like a slice or slab.

# the verb/function that creates a clod is "glom"
# "to glom" is "to steal" or to "become stuck or attached to". it is related to the
# compound "glomalin", which is a glycoprotein produced by mycorrhizal fungi in soil

# gloms a set of horizons for a single-profile SPC `p`
# the horizons are aggregated by depth using clod.hz.ids()
# the horizons are aggregated by depth using
# clod.hz.ids() defined below
glom <- function(p, z1, z2=NA, as.data.frame = FALSE) {
# aka glom.by.depth; just one type of glomming of many that we can support
# aka glom.by.depth;
if(length(p) > 1)
stop("glom is intended for single-profile SPCs", call.=FALSE)

idx <- clod.hz.ids(p, z1, z2)
if(!all(is.na(idx))) {
if(!as.data.frame) {
Expand All @@ -27,31 +24,32 @@ glom <- function(p, z1, z2=NA, as.data.frame = FALSE) {
}
}

# create a vector of horizon IDs comprising a "clod" (by depth intersection of horizons)
# returns unique index to all horizons occuring over the depth interval [z1, z2].
# z2 is optional, in which case a single horizon with depth range containing z1 is returned
clod.hz.ids <- function (p, z1, z2 = NA, as.list = FALSE)
{
# access SPC slots to get important info about p
hz <- horizons(p)
dz <- horizonDepths(p)
hzid <- hzidname(p)

# get top and bottom horizon depth vectors
tdep <- hz[[dz[1]]]
bdep <- hz[[dz[2]]]

# short circuit test of hz logic
depthlogic <- checkHzDepthLogic(p)
depthlogic <- .hzTests(tdep, bdep)
logic_tests <- c('depthLogic','missingDepth','overlapOrGap')
logic_fail <- as.logical(depthlogic[logic_tests])
if(any(logic_fail)) {
# too much could possibly go wrong in presence of overlaps/gaps/missing depths etc
warning(paste0('Horizon logic error(s) ',
paste0(logic_tests[logic_fail], collapse=","),
' found via `aqp::checkHzDepthLogic()`. Returning `NA` for ',idname(p),': ',
' found. Returning `NA` for ',idname(p),': ',
profile_id(p)), call.=FALSE)
return(NA)
}

# access SPC slots to get important info about p
hz <- horizons(p)
dz <- horizonDepths(p)
hzid <- hzidname(p)

# get top and bottom horizon depth vectors
tdep <- hz[[dz[1]]]
bdep <- hz[[dz[2]]]

# determine top depths greater/equal to z1
gt1 <- tdep >= z1

Expand All @@ -62,14 +60,14 @@ clod.hz.ids <- function (p, z1, z2 = NA, as.list = FALSE)
idx.top <- which(gt1)

if (!length(idx.top)) {
warning(paste0('Invalid upper bound. Check argument `z1`. Returning `NA` for ',idname(p),': ', profile_id(p)), call.=FALSE)
warning(paste0('Invalid upper bound. Check argument `z1`. Returning `NA` (',idname(p),': ', profile_id(p),')'), call.=FALSE)
return(NA)
}

idx.top <- idx.top[1] # always returns the top horizon

if(z1 < tdep[idx.top]) {
warning(paste0('Upper boundary `z1` (',z1,') shallower than top depth (',tdep[idx.top],') of shallowest horizon in subset. First horizon in profile @ ',min(tdep),'. (',idname(p),': ', profile_id(p), ')'), call.=FALSE)
warning(paste0('Upper boundary `z1` (',z1,') shallower than top depth (',tdep[idx.top],') of shallowest horizon in subset. (',idname(p),': ', profile_id(p), ')'), call.=FALSE)
}

# if a bottom depth of the clod interval is specified
Expand All @@ -94,7 +92,7 @@ clod.hz.ids <- function (p, z1, z2 = NA, as.list = FALSE)
idx.bot <- idx.bot[1]

if(z2 > bdep[idx.bot]) {
warning(paste0('Lower boundary `z2` (',z2,') is deeper than bottom depth of deepest horizon (', bdep[idx.bot],') in subset. ',idname(p),': ', profile_id(p)), call.=FALSE)
warning(paste0('Lower boundary `z2` (',z2,') is deeper than bottom depth of deepest horizon (', bdep[idx.bot],') in subset. (',idname(p),': ', profile_id(p),")"), call.=FALSE)
}

# not really sure how this could happen ... maybe with wrong depth units for z?
Expand Down

0 comments on commit 8e508c2

Please sign in to comment.