---
title: "What is new in aqp 2.x?"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{What is new in aqp 2.x?}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, echo=FALSE, results='hide', warning=FALSE}
knitr::opts_chunk$set(
  message = FALSE,
  warning = FALSE,
  background = '#F7F7F7',
  fig.align = 'center',
  dev = 'png',
  dpi = as.integer(Sys.getenv("R_AQP_VIGNETTE_IMAGE_DPI", unset = 32)),
  optipng = knitr::hook_optipng,
  comment = "#>"
)

# keep examples from using more than 2 cores
data.table::setDTthreads(Sys.getenv("OMP_THREAD_LIMIT", unset = 2))

options(width = 100, stringsAsFactors = FALSE, timeout = 600)
```


This is a major update to {aqp} that may create some issues for code depending on specific inputs/outputs as of {aqp} <= 1.42, particularly those relying on `slice()`, `slab()`, and `profile_compare()`. As of {aqp} 2.0, `slice()` and `profile_compare()` are deprecated, but will continue to work for the rest of calendar year 2023. There are no plans to maintain these functions beyond {aqp} 2.0. The new version of `slab()` is a drop-in replacement for the previous version.

See the manual pages for `dice()`, `NCSP()`, and `slab()`. Note that these new / updated functions perform stricter tests for horizon depth logic errors. Messages and warnings are issued when invalid depth logic is reported by `checkHzDepthLogic()`. New functions `accumulateDepths()`, `repairMissingHzDepths()`, and `fillHzGaps()` can usually salvage problematic profiles.

The `replace_na` and `add_soil_flag` arguments to `profile_compare()` are not present in `NCSP()`; missing data are always replaced by maximum dissimilarity (1 when Gower's distance metric is used) and the soil/non-soil matrix is always used to compare profiles of different depth.


## Notable Changes

 * Deprecation of `slice()` in favor of the new, faster, more robust implementation via `dice()`. Be sure to update existing code to use `dice()` from now on. Some argument names have changed. 
 * Complete overhaul of `slab()` (thanks to @brownag), with new arguments, faster back-end, and weighted aggregation implemented (finally).
 * Deprecation of `profile_compare()` in favor of the new `NCSP()` function--a complete overhaul based on Maynard et al., 2020. Note that:
   - site level attributes are now handled by `compareSites()`
   - variable weights are specified by argument
 * The functions `perturb()` and `estimatePSCS()` are now vectorized, and optimized for larger `SoilProfileCollection` objects.
 * `mixMunsell()` now uses `mixingMethod = 'exact'` by default for the simulation of subtractive color mixtures
 * `gower` package moved to SUGGESTS
 * `plotColorMixture()` now using grid graphics functions to determine color swatch geometry and setting overlap detection threshold
 * Deprecation of `rgb2munsell()` in favor of the more general `col2Munsell()`
 * Removal of `PMS2Munsell()` and support data
 * Deprecation of `coordinates()<-` and `proj4string()<-` in favor of `initSpatial()<-`
 * Removal of `rruff.sample` example XRD patterns
 * `get.ml.hz()` no longer uses the `name` argument
 
## Major changes to `plotSPC()`

 * The maximum depth range of the figure is now based on `max.depth` or `max(x)`. This means that sketches generated with {aqp} 2.x will generally have less white space at the bottom of the figure. Make more room for additional annotation or visual effect by setting the desired depth range with the `max.depth` argument.
 * Now using the `electroStatics_1D()` method for fixing horizon depth label overlap, solutions are deterministic and almost always better. Adjust label overlap adjustment strategy with `fixOverlapArgs = list(...)`.
 * Better depth axis interval heuristics (if not specified), varying based on figure depth range.
 * Depth axis adjustments via new argument `depth.axis`, logical or list
 * deprecation of arguments:
   - `plot.depth.axis`: set via `depth.axis = TRUE`, `depth.axis = FALSE`, or customize `depth.axis = list(...)`
   - `cex.depth.axis`: set via `depth.axis = list(cex = 1)`
   - `axis.line.offset`: set via `depth.axis = list(line = -2)`

## New Features

 * New example data, `wilson2022`.
 * Fast prototyping of `SoilProfileCollection` objects via `quickSPC()` and list / character templates.
 * Re-use arguments to `plotSPC()` via setting `options(.aqp.plotSPC.args = list(...))`. Set to `options(.aqp.plotSPC.args = NULL)` to disable.
 * Coarse fragment classification via `fragmentSieve()` and `fragmentClasses()`.
 * S4 `as.data.frame(<SPC>)` as shorthand for `as(<SPC>, 'data.frame')`
 * `plotSPC()` now marks truncated profiles with a ragged bottom.
 * `fixOverlap()` now has [two label-placement solvers](https://ncss-tech.github.io/aqp/articles/label-placement.html):
   - electrostatic simulation (`method = "E"`)
   - simulated annealing (`method = "S"`)
 * New [depth axis styles](https://ncss-tech.github.io/AQP/aqp/sketches.html) in `plotSPC()`.
 * New function `flagOverlappingHz()` for identifying horizons with perfect overlap
 * New function `warpHorizons()` for warping horizon thickness (inflate/deflate)
 * `simulateColor()` adds multivariate simulation in CIELAB colorspace
 

## Incremental changes, should have no effect on previous code

 * Bug fix in `plotSPC()` when `fixLabelCollisions = TRUE`, adjustments suggested to `fixOverlap()` are now scaled correctly.
 * `explainPlotSPC()` reports label adjustment index when label collision repair is enabled.
 * Aesthetic cleanup in `explainPlotSPC()`.
 * `soilColorSignature()` gains arguments and perceptual color distances (dE00) via {farver} package.
 * `as(<SPC>, "data.frame")`: Replace `plyr::join()` with `merge()`.
 * `correctAWC()`: NA handling - return NA when frags are NA.
 * `mutate_profile()`: Faster (data.table-based) evaluation of profile-level expressions.
 * `profileApply`: Add support for custom `lapply()`-like function (`APPLY.FUN`) for processing chunks. 
 * Add `.interpretHorizonColor()` outputs to `last_spc_plot` in `aqp.env` for use in custom `legend()`.
 * Add `simplify` argument to `SoilTextureLevels()` and `ssc_to_texcl()` to optionally convert to an ordered factor with maximum of 12 levels (rather than 21). This smaller list of classes excludes sand grain size variants such as fine sand, loamy coarse sand, and very fine sandy loam.
 * Major updates to `profileInformationIndex()` methods and performance boost.
 * Enhancements to `evalMissingData()`.

