From noreply at r-forge.r-project.org Sun Oct 7 12:16:19 2018 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Sun, 7 Oct 2018 12:16:19 +0200 (CEST) Subject: [CHNOSZ-commits] r331 - in pkg/CHNOSZ: . R demo inst vignettes Message-ID: <20181007101619.A788518A994@r-forge.r-project.org> Author: jedick Date: 2018-10-07 12:16:05 +0200 (Sun, 07 Oct 2018) New Revision: 331 Modified: pkg/CHNOSZ/DESCRIPTION pkg/CHNOSZ/NAMESPACE pkg/CHNOSZ/R/util.plot.R pkg/CHNOSZ/demo/yeastgfp.R pkg/CHNOSZ/inst/NEWS pkg/CHNOSZ/vignettes/anintro.Rmd Log: thermo.plot.new(): listen to par("mar") setting for active device Modified: pkg/CHNOSZ/DESCRIPTION =================================================================== --- pkg/CHNOSZ/DESCRIPTION 2018-09-27 13:46:01 UTC (rev 330) +++ pkg/CHNOSZ/DESCRIPTION 2018-10-07 10:16:05 UTC (rev 331) @@ -1,6 +1,6 @@ -Date: 2018-09-27 +Date: 2018-10-07 Package: CHNOSZ -Version: 1.1.3-38 +Version: 1.1.3-39 Title: Thermodynamic Calculations and Diagrams for Geo(bio)chemistry Authors at R: c( person("Jeffrey", "Dick", , "j3ffdick at gmail.com", role = c("aut", "cre"), Modified: pkg/CHNOSZ/NAMESPACE =================================================================== --- pkg/CHNOSZ/NAMESPACE 2018-09-27 13:46:01 UTC (rev 330) +++ pkg/CHNOSZ/NAMESPACE 2018-10-07 10:16:05 UTC (rev 331) @@ -65,7 +65,7 @@ # Imports from default packages importFrom("grDevices", "dev.cur", "dev.off", "extendrange", - "heat.colors", "png", "rainbow", "topo.colors") + "heat.colors", "png", "rainbow", "topo.colors", "dev.list") importFrom("graphics", "abline", "axTicks", "axis", "barplot", "box", "contour", "image", "legend", "lines", "mtext", "par", "plot", "plot.new", "plot.window", "points", "rect", "text", "title") Modified: pkg/CHNOSZ/R/util.plot.R =================================================================== --- pkg/CHNOSZ/R/util.plot.R 2018-09-27 13:46:01 UTC (rev 330) +++ pkg/CHNOSZ/R/util.plot.R 2018-10-07 10:16:05 UTC (rev 331) @@ -13,7 +13,14 @@ } # 20090324 mar handling: NULL - a default setting; NA - par's setting # 20090413 changed mar of top side from 2 to 2.5 - if(is.null(mar)) mar <- c(3,3.5,2.5,1) else if(is.na(mar[1])) mar <- par('mar') + marval <- c(3, 3.5, 2.5, 1) + if(identical(mar[1], NA)) marval <- par("mar") + # 20181007 get mar from the current device (if it exists) and par("mar") is not the default + if(!is.null(dev.list())) { + if(!identical(par("mar"), c(5.1, 4.1, 4.1, 2.1))) marval <- par("mar") + } + # assign marval to mar if the latter is NULL or NA + if(!is.numeric(mar)) mar <- marval par(mar=mar,mgp=mgp,tcl=0.3,las=las,xaxs=axs,yaxs=axs,cex=cex,lwd=lwd,col=col,fg=col, ...) plot.new() plot.window(xlim=xlim,ylim=ylim) Modified: pkg/CHNOSZ/demo/yeastgfp.R =================================================================== --- pkg/CHNOSZ/demo/yeastgfp.R 2018-09-27 13:46:01 UTC (rev 330) +++ pkg/CHNOSZ/demo/yeastgfp.R 2018-10-07 10:16:05 UTC (rev 331) @@ -28,11 +28,11 @@ a <- affinity(H2O=c(-5, 0, 256), O2=c(-80, -66, 256)) # setup the plot layout(matrix(c(1, 1,2:7), byrow=TRUE, nrow=4), heights=c(0.7, 3, 3, 3)) -par(mar=c(0, 0, 0, 0)) +opar <- par(mar=c(0, 0, 0, 0)) plot.new() text(0.5, 0.7, expression("Proteins in subcellular locations of"~italic("S. cerevisiae")~"(Dick, 2009)"), cex=1.5) text(0.5, 0.2, describe.basis(ibasis=c(1, 3, 4, 6), oneline=TRUE), cex=1.5) -opar <- par(mar=c(3, 4, 1, 1), xpd=TRUE) +par(mar=c(3, 4, 1, 1), xpd=TRUE) fill <- heat.colors(length(names)) inames <- 1:length(names) for(i in 1:length(nloc)) { @@ -45,6 +45,7 @@ } # return to plot defaults layout(matrix(1)) +par(xpd=FALSE) par(opar) ## Localizations and abundances of proteins from YeastGFP are used here Modified: pkg/CHNOSZ/inst/NEWS =================================================================== --- pkg/CHNOSZ/inst/NEWS 2018-09-27 13:46:01 UTC (rev 330) +++ pkg/CHNOSZ/inst/NEWS 2018-10-07 10:16:05 UTC (rev 331) @@ -1,4 +1,4 @@ -CHANGES IN CHNOSZ 1.1.3-38 (2018-09-27) +CHANGES IN CHNOSZ 1.1.3-39 (2018-10-07) --------------------------------------- THERMODYNAMIC DATA @@ -58,10 +58,15 @@ - diagram(): rename 'what' argument to 'type'. -- digram(): add new type of diagram, 'saturation', which is used to +- diagram(): add new type of diagram, 'saturation', which is used to plot saturation lines for minerals (where their affinity equals zero). +- thermo.plot.new() and, by extension, diagram(), now "listen" to the + setting of par("mar"). However, if a new plot is being made, or the + device has the default setting of mar from par(), mar is (re)set to + the default value in thermo.plot.new(). + BUG FIXES - Fix a bug where subcrt()$reaction$coeffs was incorrect for reactions Modified: pkg/CHNOSZ/vignettes/anintro.Rmd =================================================================== --- pkg/CHNOSZ/vignettes/anintro.Rmd 2018-09-27 13:46:01 UTC (rev 330) +++ pkg/CHNOSZ/vignettes/anintro.Rmd 2018-10-07 10:16:05 UTC (rev 331) @@ -209,7 +209,7 @@ * Use `subcrt()` to calculate standard molal thermodynamic properties. -```{r bsad_adenine, fig.margin=TRUE, fig.width=4, fig.height=4, small.mar=TRUE, dpi=dpi, out.width="100%", echo=FALSE, message=FALSE, results="hide", fig.cap="Nucleobase equal-activity diagram at T = 100 ?C.", cache=TRUE, pngquant=pngquant, timeit=timeit} +```{r bsad_adenine, fig.margin=TRUE, fig.width=4, fig.height=4, dpi=dpi, out.width="100%", echo=FALSE, message=FALSE, results="hide", fig.cap="Nucleobase equal-activity diagram at T = 100 ?C.", cache=TRUE, pngquant=pngquant, timeit=timeit} basis("CHNOSe") species(c("adenine", "cytosine", "guanine", "thymine", "uracil")) a <- affinity(H2O = c(-12, -0), Eh = c(-0.4, -0.2), T = 100) @@ -220,7 +220,7 @@ subcrt("adenine", T = 100) ``` -```{r equil_adenine, fig.margin=TRUE, fig.width=4, fig.height=4, small.mar=TRUE, dpi=dpi, out.width="100%", echo=FALSE, message=FALSE, results="hide", fig.cap="Activities of nucleobases in metastable equilibrium at T = 100 ?C.", cache=TRUE, pngquant=pngquant, timeit=timeit} +```{r equil_adenine, fig.margin=TRUE, fig.width=4, fig.height=4, dpi=dpi, out.width="100%", echo=FALSE, message=FALSE, results="hide", fig.cap="Activities of nucleobases in metastable equilibrium at T = 100 ?C.", cache=TRUE, pngquant=pngquant, timeit=timeit} basis("e-", 3.6) a <- affinity(H2O = c(-12, 0), T = 100) e <- equilibrate(a) @@ -614,7 +614,7 @@ That is, running `affinity()``$values` again would give the same result. ``` -```{r EhpH_plot, fig.margin=TRUE, fig.width=4, fig.height=4, small.mar=TRUE, dpi=dpi, out.width="100%", echo=FALSE, message=FALSE, cache=TRUE, fig.cap="Aqueous sulfur species at 25 ?C.", pngquant=pngquant, timeit=timeit} +```{r EhpH_plot, fig.margin=TRUE, fig.width=4, fig.height=4, dpi=dpi, out.width="100%", echo=FALSE, message=FALSE, cache=TRUE, fig.cap="Aqueous sulfur species at 25 ?C.", pngquant=pngquant, timeit=timeit} a <- affinity(pH = c(0, 12), Eh = c(-0.5, 1)) diagram(a, fill = "heat") water.lines(a) @@ -693,7 +693,7 @@ The first call to `diagram()` plots the species of interest; the second adds the predominance fields of the basis species. We turn off the gray coloring beyond the water stability limits (`limit.water`) but plot the red dotted lines using `water.lines()`: -```{r copper_mosaic, fig.margin=TRUE, fig.width=4, fig.height=4, small.mar=TRUE, dpi=dpi, out.width="100%", message=FALSE, cache=TRUE, fig.cap="Copper minerals and aqueous complexes with chloride, 200 ?C.", pngquant=pngquant, timeit=timeit} +```{r copper_mosaic, fig.margin=TRUE, fig.width=4, fig.height=4, dpi=dpi, out.width="100%", message=FALSE, cache=TRUE, fig.cap="Copper minerals and aqueous complexes with chloride, 200 ?C.", pngquant=pngquant, timeit=timeit} T <- 200 res <- 200 bases <- c("H2S", "HS-", "HSO4-", "SO4-2") @@ -714,7 +714,7 @@ For instance, we can use H2 or `r o2` in place of *e*-. To do that, let's write a function to swap those basis species and make a diagram. We use R's `do.call()` to construct the argument list for `mosaic()`; this way, the name of the `newvar` argument to our function indicates the chosen variable. -```{r mosaicfun, fig.fullwidth=TRUE, fig.width=9, fig.height=3, small.mar=TRUE, dpi=dpi, out.width="85%", message=FALSE, results="hide", cache=TRUE, fig.cap="The same chemical system projected into different sets of basis species.", pngquant=pngquant, timeit=timeit} +```{r mosaicfun, fig.fullwidth=TRUE, fig.width=9, fig.height=3, dpi=dpi, out.width="85%", message=FALSE, results="hide", cache=TRUE, fig.cap="The same chemical system projected into different sets of basis species.", pngquant=pngquant, timeit=timeit} mosaicfun <- function(newvar, T = 200) { swap.basis("e-", names(newvar)) if (names(newvar) == "O2") basis("O2", "gas") @@ -779,7 +779,7 @@ a$values <- lapply(a$values, `*`, -0.001) ``` -```{r rainbow_diagram, fig.margin=TRUE, fig.width=4, fig.height=4, small.mar=TRUE, dpi=dpi, out.width="100%", echo=FALSE, message=FALSE, cache=TRUE, fig.cap="Affinities of organic synthesis in a hydrothermal system, after Shock and Canovas (2010).", pngquant=pngquant, timeit=timeit} +```{r rainbow_diagram, fig.margin=TRUE, fig.width=4, fig.height=4, dpi=dpi, out.width="100%", echo=FALSE, message=FALSE, cache=TRUE, fig.cap="Affinities of organic synthesis in a hydrothermal system, after Shock and Canovas (2010).", pngquant=pngquant, timeit=timeit} diagram(a, balance = 1, ylim = c(-100, 100), ylab = axis.label("A", prefix="k"), col = rainbow(8), lwd = 2, bg = "slategray3") abline(h = 0, lty = 2, lwd = 2) @@ -842,7 +842,7 @@ ``` -```{r demo_buffer_noecho, fig.margin=TRUE, fig.width=4, fig.height=4, small.mar=TRUE, dpi=dpi, out.width="100%", message=FALSE, echo=FALSE, cache=TRUE, fig.cap="Values of logfH2 corresponding to mineral buffers or to given activities of aqueous species.", pngquant=pngquant, timeit=timeit} +```{r demo_buffer_noecho, fig.margin=TRUE, fig.width=4, fig.height=4, dpi=dpi, out.width="100%", message=FALSE, echo=FALSE, cache=TRUE, fig.cap="Values of logfH2 corresponding to mineral buffers or to given activities of aqueous species.", pngquant=pngquant, timeit=timeit} demo(buffer, echo = FALSE) ``` Et voil?! We have found log*a*H2S and `r logfO2` that are compatible with the coexistence of the three minerals. @@ -888,7 +888,7 @@ The method based on the Boltzmann equation is fast, but is applicable only to systems where the coefficient on the balanced basis species in each of the formation reactions is one. The reaction-matrix method is slower, but can be applied to systems were the balanced basis species has reaction coefficients other than one. -```{r bjerrum_diagram, fig.margin=TRUE, fig.width=3, fig.height=6, small.mar=TRUE, dpi=dpi, out.width="100%", echo=FALSE, results="hide", message=FALSE, cache=TRUE, fig.cap="Three views of carbonate speciation: affinity, activity, degree of formation.", pngquant=pngquant, timeit=timeit} +```{r bjerrum_diagram, fig.margin=TRUE, fig.width=3, fig.height=6, dpi=dpi, out.width="100%", echo=FALSE, results="hide", message=FALSE, cache=TRUE, fig.cap="Three views of carbonate speciation: affinity, activity, degree of formation.", pngquant=pngquant, timeit=timeit} par(mfrow = c(3, 1)) basis("CHNOS+") species(c("CO2", "HCO3-", "CO3-2")) @@ -1007,7 +1007,7 @@ We do this by setting the names and line types for the *other* species to values that prevent them from being plotted: ```{r groups_diagram, echo=-(1:4), eval=FALSE} ``` -```{r groups_diagram, fig.fullwidth=TRUE, fig.width=9, fig.height=3, small.mar=TRUE, dpi=dpi, out.width="85%", echo=FALSE, message=FALSE, results="hide", cache=TRUE, fig.cap="Distribution of inorganic and groups of organic species (left plot) and of alcohols and ketones (middle and right plots) as a function of T, pH, and logfO2.", pngquant=pngquant, timeit=timeit} +```{r groups_diagram, fig.fullwidth=TRUE, fig.width=9, fig.height=3, dpi=dpi, out.width="85%", echo=FALSE, message=FALSE, results="hide", cache=TRUE, fig.cap="Distribution of inorganic and groups of organic species (left plot) and of alcohols and ketones (middle and right plots) as a function of T, pH, and logfO2.", pngquant=pngquant, timeit=timeit} ``` ## Balancing differently @@ -1033,7 +1033,7 @@ There, we set `balance = 1`, which indicates that moles of species are conserved; this is equivalent to balancing on the amino acid backbone. In the remaining plots, the balance is set to each of the basis species in turn (except for O2), then on volume. `expr.species()` together with R's `substitute()` is used to make titles that include formatted chemical formulas: -```{r aafun, fig.fullwidth=TRUE, fig.width=12.5, fig.height=2.5, small.mar=TRUE, dpi=dpi, out.width="100%", message=FALSE, results="hide", fig.cap="Plots of maximum affinity at 250 ?C and 265 bar using different reaction balances for 20 amino acids.", cache=TRUE, pngquant=pngquant, timeit=timeit} +```{r aafun, fig.fullwidth=TRUE, fig.width=12.5, fig.height=2.5, dpi=dpi, out.width="100%", message=FALSE, results="hide", fig.cap="Plots of maximum affinity at 250 ?C and 265 bar using different reaction balances for 20 amino acids.", cache=TRUE, pngquant=pngquant, timeit=timeit} aafun <- function(balance) { diagram(a, balance = balance, fill = col) blab <- expr.species(balance) @@ -1519,7 +1519,7 @@ Here, we plot the information-theoretic free energy ?*Ginf* (calculated from the relative entropy or Kullback--Leibler divergence): ```{r yeastplot, eval=FALSE, echo=10} ``` -```{r yeastplot, fig.fullwidth=TRUE, fig.width=7.5, fig.height=2.5, small.mar=TRUE, dpi=ifelse(dpi==50, 50, 100), out.width="85%", echo=FALSE, message=FALSE, results="hide", cache=TRUE, fig.cap="ER-to-Golgi proteins: calculations without and with length normalization, and free energy difference between experimental and calculated abundances in metastable equilibrium with normalization.", pngquant=pngquant, timeit=timeit} +```{r yeastplot, fig.fullwidth=TRUE, fig.width=7.5, fig.height=2.5, dpi=ifelse(dpi==50, 50, 100), out.width="85%", echo=FALSE, message=FALSE, results="hide", cache=TRUE, fig.cap="ER-to-Golgi proteins: calculations without and with length normalization, and free energy difference between experimental and calculated abundances in metastable equilibrium with normalization.", pngquant=pngquant, timeit=timeit} ``` The minimum free energy difference occurs near `r logfO2` = -78. @@ -1573,7 +1573,7 @@ Here, `adj = 0` makes the labels left-aligned, `dy = 0.1` adds a *y* offset to the labels, and `format.names = FALSE` prevents formatting of the names as if they were chemical formulas (that causes subscripted numbers to appear). The last few lines are used to make a second *x* axis, using a label generated with `axis.label()`: -```{r Shh_diagram, fig.margin=TRUE, fig.width=4, fig.height=4, small.mar=TRUE, dpi=dpi, out.width="100%", echo=FALSE, results="hide", message=FALSE, fig.cap="Per-residue affinities for formation of transcription factors relative to Shh.", cache=TRUE, pngquant=pngquant, timeit=timeit} +```{r Shh_diagram, fig.margin=TRUE, fig.width=4, fig.height=4, dpi=dpi, out.width="100%", echo=FALSE, results="hide", message=FALSE, fig.cap="Per-residue affinities for formation of transcription factors relative to Shh.", cache=TRUE, pngquant=pngquant, timeit=timeit} # line type, width, and color twc <- lapply(c(3, 1, 1), rep, length(pname)) ihigh <- c(2, 5, 7, 8, 1) @@ -1727,7 +1727,7 @@ We read a data file of amino acid compositions produced in that study, taking those labeled "transferase". Then we add the proteins and get their indices using `add.protein()`, set the basis, calculate the affinities, and make a potential diagram with temperature and activity of dissolved hydrogen as variables: -```{r bison_transferase, fig.margin=TRUE, fig.width=4, fig.height=4, small.mar=TRUE, dpi=dpi, out.width="100%", echo=FALSE, results="hide", message=FALSE, fig.cap='Potential diagram for metagenomically identified sequences of transferases in Bison Pool hot spring. See also the vignette [*Hot-spring proteins in CHNOSZ*](hotspring.pdf).', cache=TRUE, pngquant=pngquant, timeit=timeit} +```{r bison_transferase, fig.margin=TRUE, fig.width=4, fig.height=4, dpi=dpi, out.width="100%", echo=FALSE, results="hide", message=FALSE, fig.cap='Potential diagram for metagenomically identified sequences of transferases in Bison Pool hot spring. See also the vignette [*Hot-spring proteins in CHNOSZ*](hotspring.pdf).', cache=TRUE, pngquant=pngquant, timeit=timeit} file <- system.file("extdata/protein/DS11.csv", package = "CHNOSZ") aa <- read.csv(file, as.is = TRUE) aa <- aa[grep("transferase", aa$protein), ] @@ -1868,7 +1868,7 @@ ```{r smoker_plot, eval=FALSE, echo=23:25} ``` -```{r smoker_plot, fig.fullwidth=TRUE, fig.width=9, fig.height=5, small.mar=TRUE, dpi=dpi, out.width="85%", echo=FALSE, message=FALSE, results="hide", cache=TRUE, fig.cap="Optimization of a thermodynamic model for relative abundances of amino acids in a 270 ?C black smoker fluid using 1, 2, or 3 variables (left to right).", pngquant=pngquant, timeit=timeit} +```{r smoker_plot, fig.fullwidth=TRUE, fig.width=9, fig.height=5, dpi=dpi, out.width="85%", echo=FALSE, message=FALSE, results="hide", cache=TRUE, fig.cap="Optimization of a thermodynamic model for relative abundances of amino acids in a 270 ?C black smoker fluid using 1, 2, or 3 variables (left to right).", pngquant=pngquant, timeit=timeit} ``` The calculation using `findit()`, in which the added variable log*a*`r h2o` optimizes to ca. -2.4, shows that measured concentrations of 6 amino acids fall within 1--2 log units of the relative abundances in metastable equilibrium. From noreply at r-forge.r-project.org Tue Oct 9 07:17:31 2018 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Tue, 9 Oct 2018 07:17:31 +0200 (CEST) Subject: [CHNOSZ-commits] r332 - in pkg/CHNOSZ: . R inst man vignettes Message-ID: <20181009051731.4565418A6B0@r-forge.r-project.org> Author: jedick Date: 2018-10-09 07:17:30 +0200 (Tue, 09 Oct 2018) New Revision: 332 Modified: pkg/CHNOSZ/DESCRIPTION pkg/CHNOSZ/R/diagram.R pkg/CHNOSZ/inst/NEWS pkg/CHNOSZ/man/diagram.Rd pkg/CHNOSZ/vignettes/hotspring.Rnw pkg/CHNOSZ/vignettes/hotspring.lyx Log: diagram(): accept numeric 'names' argument to indicate subset of names to plot Modified: pkg/CHNOSZ/DESCRIPTION =================================================================== --- pkg/CHNOSZ/DESCRIPTION 2018-10-07 10:16:05 UTC (rev 331) +++ pkg/CHNOSZ/DESCRIPTION 2018-10-09 05:17:30 UTC (rev 332) @@ -1,6 +1,6 @@ -Date: 2018-10-07 +Date: 2018-10-09 Package: CHNOSZ -Version: 1.1.3-39 +Version: 1.1.3-40 Title: Thermodynamic Calculations and Diagrams for Geo(bio)chemistry Authors at R: c( person("Jeffrey", "Dick", , "j3ffdick at gmail.com", role = c("aut", "cre"), Modified: pkg/CHNOSZ/R/diagram.R =================================================================== --- pkg/CHNOSZ/R/diagram.R 2018-10-07 10:16:05 UTC (rev 331) +++ pkg/CHNOSZ/R/diagram.R 2018-10-09 05:17:30 UTC (rev 332) @@ -215,7 +215,8 @@ ## make up some names for lines/fields if they are missing is.pname <- FALSE - if(missing(names)) { + onames <- names + if(missing(names) | all(is.numeric(names))) { # properties of basis species or reactions? if(eout$property %in% c("G.basis", "logact.basis")) names <- rownames(eout$basis) else { @@ -241,6 +242,12 @@ " (", eout$species$state[isdup], ")", sep="") } } + # numeric values indicate a subset 20181007 + if(all(is.numeric(onames))) { + if(all(onames > 0)) names[-onames] <- "" + else if(all(onames < 0)) names[-onames] <- "" + else stop("numeric 'names' should be all positive or all negative") + } ## apply formatting to chemical formulas 20170204 if(all(grepl("_", names))) is.pname <- TRUE Modified: pkg/CHNOSZ/inst/NEWS =================================================================== --- pkg/CHNOSZ/inst/NEWS 2018-10-07 10:16:05 UTC (rev 331) +++ pkg/CHNOSZ/inst/NEWS 2018-10-09 05:17:30 UTC (rev 332) @@ -1,4 +1,4 @@ -CHANGES IN CHNOSZ 1.1.3-39 (2018-10-07) +CHANGES IN CHNOSZ 1.1.3-40 (2018-10-09) --------------------------------------- THERMODYNAMIC DATA @@ -67,6 +67,9 @@ device has the default setting of mar from par(), mar is (re)set to the default value in thermo.plot.new(). +- diagram(): numeric 'names' now indicates subset of species names to + include as labels on the plot. + BUG FIXES - Fix a bug where subcrt()$reaction$coeffs was incorrect for reactions Modified: pkg/CHNOSZ/man/diagram.Rd =================================================================== --- pkg/CHNOSZ/man/diagram.Rd 2018-10-07 10:16:05 UTC (rev 331) +++ pkg/CHNOSZ/man/diagram.Rd 2018-10-09 05:17:30 UTC (rev 332) @@ -95,14 +95,19 @@ 2-D diagrams, for two variables, are plotted as predominance fields. The allowed variables are any that \code{\link{affinity}} accepts: temperature, pressure, or the chemical activities of the basis species +A new plot is started unless \code{add} is TRUE. +If \code{plot.it} is FALSE, no plot will be generated but all the intermediate computations will be performed and the results returned. + +Line or field labels use the names of the species as provided in \code{eout}; formatting is applied to chemical formuls unless \code{format.names} is FALSE. +Use the \code{names} argument to override the default species names. +Alternatively, supply a numeric value to \code{names} to indicate the subset of default names that should or shouldn't be plotted (positive and negative indices, respectively). +Use \code{col.names} and \code{cex.names} to change the colors and size of the labels. +Use \code{cex} and \code{cex.axis} to adjust the overall character expansion factors (see \code{\link{par}}) and those of the axis labels. +The x- and y-axis labels are automatically generated unless they are supplied in \code{xlab} and \code{ylab}. + If \code{groups} is supplied, the activities of the species identified in each numeric element of this list are multiplied by the balance coefficients of the species, then summed together. The names of the list are used to label the lines or fields for the summed activities of the resulting groups. -For all diagrams, the \code{names} of the species and their colors in \code{col.names} can be changed, as can \code{cex}, \code{cex.names}, and \code{cex.axis} to adjust the overall character expansion factors (see \code{\link{par}}) and those of the species names and axis labels. -The x- and y-axis labels are automatically generated unless they are supplied in \code{xlab} and \code{ylab}. -A new plot is started unless \code{add} is TRUE. -If \code{plot.it} is FALSE, no plot will be generated but all the intermediate computations will be performed and the results returned. - \code{find.tp} finds the locations in a matrix of integers that are surrounded by the greatest number of different values. The function counts the unique values in a 3x3 grid around each point and returns a matrix of indices (similar to \code{\link{which}(..., arr.ind = TRUE)}) for the maximum count (ties result in more than one pair of indices). It can be used with the output from \code{diagram} for calculations in 2 dimensions to approximately locate the triple points on the diagram. Modified: pkg/CHNOSZ/vignettes/hotspring.Rnw =================================================================== --- pkg/CHNOSZ/vignettes/hotspring.Rnw 2018-10-07 10:16:05 UTC (rev 331) +++ pkg/CHNOSZ/vignettes/hotspring.Rnw 2018-10-09 05:17:30 UTC (rev 332) @@ -1,4 +1,4 @@ -%% LyX 2.2.2 created this file. For more info, see http://www.lyx.org/. +%% LyX 2.3.0 created this file. For more info, see http://www.lyx.org/. %% Do not edit unless you really know what you are doing. \documentclass[english]{article} \usepackage{mathpazo} @@ -350,7 +350,7 @@ par(mfrow=c(1, 2)) # first plot a <- affinity(T=Tlim, H2=c(-7, -4)) -diagram(a, fill=NULL, names=1:5, normalize=TRUE) +diagram(a, fill=NULL, names=as.character(1:5), normalize=TRUE) lines(Tlim, get.logaH2(Tlim), lty=3) # second plot species(1:5, -3) @@ -423,7 +423,7 @@ for(annot in c("overall", "transferase", "synthase")) { ip <- ip.annot[aa.annot$protein==annot] a <- affinity(T=c(50, 100), H2=c(-7, -4), iprotein=ip) - diagram(a, fill=NULL, names=1:5, normalize=TRUE) + diagram(a, fill=NULL, names=as.character(1:5), normalize=TRUE) # add logaH2-T line lines(par("usr")[1:2], get.logaH2(par("usr")[1:2]), lty=3) # add a title Modified: pkg/CHNOSZ/vignettes/hotspring.lyx =================================================================== --- pkg/CHNOSZ/vignettes/hotspring.lyx 2018-10-07 10:16:05 UTC (rev 331) +++ pkg/CHNOSZ/vignettes/hotspring.lyx 2018-10-09 05:17:30 UTC (rev 332) @@ -1,5 +1,5 @@ -#LyX 2.2 created this file. For more info see http://www.lyx.org/ -\lyxformat 508 +#LyX 2.3 created this file. For more info see http://www.lyx.org/ +\lyxformat 544 \begin_document \begin_header \save_transient_properties true @@ -31,6 +31,8 @@ \font_osf false \font_sf_scale 100 100 \font_tt_scale 100 100 +\use_microtype false +\use_dash_ligatures false \graphics default \default_output_format default \output_sync 0 @@ -70,6 +72,7 @@ \suppress_date false \justification true \use_refstyle 0 +\use_minted 0 \index Index \shortcut idx \color #008000 @@ -82,7 +85,10 @@ \tocdepth 3 \paragraph_separation indent \paragraph_indentation default -\quotes_language english +\is_math_indent 0 +\math_numbering_side default +\quotes_style english +\dynamic_quotes 0 \papercolumns 1 \papersides 1 \paperpagestyle default @@ -191,6 +197,7 @@ \begin_inset CommandInset citation LatexCommand citep key "DS11,DS13" +literal "true" \end_inset @@ -244,6 +251,7 @@ \begin_inset CommandInset citation LatexCommand citep key "DLH06" +literal "true" \end_inset @@ -251,6 +259,7 @@ \begin_inset CommandInset citation LatexCommand citep key "LD12" +literal "true" \end_inset @@ -430,6 +439,7 @@ LatexCommand href name "DOI link" target "https://doi.org/10.1371/journal.pone.0022782.g005" +literal "false" \end_inset @@ -575,6 +585,7 @@ \begin_inset CommandInset citation LatexCommand citep key "WE08" +literal "true" \end_inset @@ -918,6 +929,7 @@ LatexCommand href name "plot 1" target "https://doi.org/10.1371/journal.pone.0022782.g004" +literal "false" \end_inset @@ -926,6 +938,7 @@ LatexCommand href name "plot 2" target "https://doi.org/10.1371/journal.pone.0072395.g001" +literal "false" \end_inset @@ -1161,6 +1174,7 @@ \begin_inset CommandInset citation LatexCommand cite key "DS11" +literal "true" \end_inset @@ -1168,6 +1182,7 @@ \begin_inset CommandInset citation LatexCommand cite key "DS13" +literal "true" \end_inset @@ -1264,6 +1279,7 @@ LatexCommand href name "DOI link" target "https://doi.org/10.1371/journal.pone.0022782.t005" +literal "false" \end_inset @@ -1328,6 +1344,7 @@ \begin_inset CommandInset citation LatexCommand citep key "DS11" +literal "true" \end_inset @@ -1483,7 +1500,7 @@ \begin_layout Plain Layout -diagram(a, fill=NULL, names=1:5, normalize=TRUE) +diagram(a, fill=NULL, names=as.character(1:5), normalize=TRUE) \end_layout \begin_layout Plain Layout @@ -1561,6 +1578,7 @@ LatexCommand href name "DOI link" target "https://doi.org/10.1371/journal.pone.0022782.g005" +literal "false" \end_inset @@ -1703,6 +1721,7 @@ LatexCommand href name "DOI link" target "https://doi.org/10.1371/journal.pone.0022782.g007" +literal "false" \end_inset @@ -1818,7 +1837,7 @@ \begin_layout Plain Layout - diagram(a, fill=NULL, names=1:5, normalize=TRUE) + diagram(a, fill=NULL, names=as.character(1:5), normalize=TRUE) \end_layout \begin_layout Plain Layout @@ -1866,6 +1885,7 @@ LatexCommand href name "DOI link" target "https://doi.org/10.1371/journal.pone.0072395.g002" +literal "false" \end_inset @@ -2277,6 +2297,7 @@ LatexCommand href name "DOI link" target "https://doi.org/10.1371/journal.pone.0072395.g003" +literal "false" \end_inset @@ -2326,6 +2347,7 @@ \begin_inset CommandInset citation LatexCommand citep key "BPJ85" +literal "true" \end_inset @@ -2377,6 +2399,7 @@ \begin_inset CommandInset citation LatexCommand citep key "DS11" +literal "true" \end_inset @@ -2787,6 +2810,7 @@ LatexCommand href name "plot 1" target "https://doi.org/10.1371/journal.pone.0022782.g009" +literal "false" \end_inset @@ -2795,6 +2819,7 @@ LatexCommand href name "plot 2" target "https://doi.org/10.1371/journal.pone.0072395.g004" +literal "false" \end_inset @@ -2973,6 +2998,7 @@ LatexCommand href name "DOI link" target "https://doi.org/10.1371/journal.pone.0072395.g005" +literal "false" \end_inset @@ -3118,6 +3144,7 @@ LatexCommand href name "DOI link" target "https://doi.org/10.1371/journal.pone.0072395.g006" +literal "false" \end_inset From noreply at r-forge.r-project.org Fri Oct 12 15:02:44 2018 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Fri, 12 Oct 2018 15:02:44 +0200 (CEST) Subject: [CHNOSZ-commits] r333 - in pkg/CHNOSZ: . R inst man Message-ID: <20181012130244.5305418B1EE@r-forge.r-project.org> Author: jedick Date: 2018-10-12 15:02:43 +0200 (Fri, 12 Oct 2018) New Revision: 333 Modified: pkg/CHNOSZ/DESCRIPTION pkg/CHNOSZ/R/diagram.R pkg/CHNOSZ/inst/NEWS pkg/CHNOSZ/man/diagram.Rd Log: diagram(): add 'family', 'font', 'bold', 'italic' arguments Modified: pkg/CHNOSZ/DESCRIPTION =================================================================== --- pkg/CHNOSZ/DESCRIPTION 2018-10-09 05:17:30 UTC (rev 332) +++ pkg/CHNOSZ/DESCRIPTION 2018-10-12 13:02:43 UTC (rev 333) @@ -1,6 +1,6 @@ -Date: 2018-10-09 +Date: 2018-10-11 Package: CHNOSZ -Version: 1.1.3-40 +Version: 1.1.3-41 Title: Thermodynamic Calculations and Diagrams for Geo(bio)chemistry Authors at R: c( person("Jeffrey", "Dick", , "j3ffdick at gmail.com", role = c("aut", "cre"), Modified: pkg/CHNOSZ/R/diagram.R =================================================================== --- pkg/CHNOSZ/R/diagram.R 2018-10-09 05:17:30 UTC (rev 332) +++ pkg/CHNOSZ/R/diagram.R 2018-10-12 13:02:43 UTC (rev 333) @@ -29,7 +29,8 @@ col=par("col"), col.names=par("col"), fill=NULL, fill.NA="slategray1", limit.water=TRUE, # field and line labels - names=NULL, format.names=TRUE, adj=0.5, dy=0, srt=0, + names=NULL, format.names=TRUE, bold=FALSE, italic=FALSE, + font=par("font"), family=par("family"), adj=0.5, dy=0, srt=0, # title and legend main=NULL, legend.x=NA, # plotting controls @@ -253,7 +254,11 @@ if(all(grepl("_", names))) is.pname <- TRUE if(format.names & !is.pname) { exprnames <- as.expression(names) - for(i in seq_along(exprnames)) exprnames[[i]] <- expr.species(exprnames[[i]]) + for(i in seq_along(exprnames)) { + exprnames[[i]] <- expr.species(exprnames[[i]]) + if(bold) exprnames[[i]] <- substitute(bold(a), list(a=exprnames[[i]])) + if(italic) exprnames[[i]] <- substitute(italic(a), list(a=exprnames[[i]])) + } names <- exprnames } @@ -334,7 +339,7 @@ } # also include y-offset (dy) and y-adjustment (labels bottom-aligned with the line) # .. and srt (string rotation) 20171127 - text(xvalues[imax], plotvals[[i]][imax] + dy[i], labels=names[i], adj=c(thisadj, 0), cex=cex.names, srt=srt[i]) + text(xvalues[imax], plotvals[[i]][imax] + dy[i], labels=names[i], adj=c(thisadj, 0), cex=cex.names, srt=srt[i], font=font, family=family) } } else legend(x=legend.x, lty=lty, legend=names, col=col, cex=cex.names, lwd=lwd, ...) } @@ -501,7 +506,7 @@ # plot field labels # the cex argument in this function specifies the character # expansion of the labels relative to the current - if(!is.null(names) & any(inames)) text(namesx, namesy, labels=names[inames], cex=cex.names, col=col.names[inames]) + if(!is.null(names) & any(inames)) text(namesx, namesy, labels=names[inames], cex=cex.names, col=col.names[inames], font=font, family=family) return(list(namesx=namesx, namesy=namesy, inames=which(inames))) } Modified: pkg/CHNOSZ/inst/NEWS =================================================================== --- pkg/CHNOSZ/inst/NEWS 2018-10-09 05:17:30 UTC (rev 332) +++ pkg/CHNOSZ/inst/NEWS 2018-10-12 13:02:43 UTC (rev 333) @@ -1,4 +1,4 @@ -CHANGES IN CHNOSZ 1.1.3-40 (2018-10-09) +CHANGES IN CHNOSZ 1.1.3-41 (2018-10-11) --------------------------------------- THERMODYNAMIC DATA @@ -70,6 +70,11 @@ - diagram(): numeric 'names' now indicates subset of species names to include as labels on the plot. +- diagram(): new argument 'family' to select the font family for species + names (labels on the plot). New arguments 'bold' and 'italic' apply to + formatted names (e.g. chemical formulas), and 'font' applies to those + without formatting. + BUG FIXES - Fix a bug where subcrt()$reaction$coeffs was incorrect for reactions Modified: pkg/CHNOSZ/man/diagram.Rd =================================================================== --- pkg/CHNOSZ/man/diagram.Rd 2018-10-09 05:17:30 UTC (rev 332) +++ pkg/CHNOSZ/man/diagram.Rd 2018-10-12 13:02:43 UTC (rev 333) @@ -27,7 +27,8 @@ col=par("col"), col.names=par("col"), fill=NULL, fill.NA="slategray1", limit.water=TRUE, # field and line labels - names=NULL, format.names=TRUE, adj=0.5, dy=0, srt=0, + names=NULL, format.names=TRUE, bold = FALSE, italic = FALSE, + font = par("font"), family = par("family"), adj=0.5, dy=0, srt=0, # title and legend main=NULL, legend.x=NA, # plotting controls @@ -69,6 +70,10 @@ \item{limit.water}{logical, set NA values beyond water stability limits?} \item{names}{character, names of species for activity lines or predominance fields} \item{format.names}{logical, apply formatting to chemical formulas?} + \item{bold}{logical, use bold formatting for names?} + \item{italic}{logical, use italic formatting for names?} + \item{font}{character, font type for names (has no effect if \code{format.names} is TRUE)} + \item{family}{character, font family for names} \item{adj}{numeric, adjustment for line labels} \item{dy}{numeric, y offset for line labels} \item{srt}{numeric, rotation for line labels} From noreply at r-forge.r-project.org Tue Oct 30 03:55:57 2018 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Tue, 30 Oct 2018 03:55:57 +0100 (CET) Subject: [CHNOSZ-commits] r334 - in pkg/CHNOSZ: . R demo inst man man/macros Message-ID: <20181030025557.9D48C18B391@r-forge.r-project.org> Author: jedick Date: 2018-10-30 03:55:56 +0100 (Tue, 30 Oct 2018) New Revision: 334 Modified: pkg/CHNOSZ/DESCRIPTION pkg/CHNOSZ/NAMESPACE pkg/CHNOSZ/R/diagram.R pkg/CHNOSZ/demo/affinity.R pkg/CHNOSZ/inst/NEWS pkg/CHNOSZ/man/diagram.Rd pkg/CHNOSZ/man/macros/macros.Rd Log: diagram(): add 'lines' to output Modified: pkg/CHNOSZ/DESCRIPTION =================================================================== --- pkg/CHNOSZ/DESCRIPTION 2018-10-12 13:02:43 UTC (rev 333) +++ pkg/CHNOSZ/DESCRIPTION 2018-10-30 02:55:56 UTC (rev 334) @@ -1,6 +1,6 @@ -Date: 2018-10-11 +Date: 2018-10-30 Package: CHNOSZ -Version: 1.1.3-41 +Version: 1.1.3-42 Title: Thermodynamic Calculations and Diagrams for Geo(bio)chemistry Authors at R: c( person("Jeffrey", "Dick", , "j3ffdick at gmail.com", role = c("aut", "cre"), Modified: pkg/CHNOSZ/NAMESPACE =================================================================== --- pkg/CHNOSZ/NAMESPACE 2018-10-12 13:02:43 UTC (rev 333) +++ pkg/CHNOSZ/NAMESPACE 2018-10-30 02:55:56 UTC (rev 334) @@ -65,7 +65,8 @@ # Imports from default packages importFrom("grDevices", "dev.cur", "dev.off", "extendrange", - "heat.colors", "png", "rainbow", "topo.colors", "dev.list") + "heat.colors", "png", "rainbow", "topo.colors", "dev.list", + "contourLines") importFrom("graphics", "abline", "axTicks", "axis", "barplot", "box", "contour", "image", "legend", "lines", "mtext", "par", "plot", "plot.new", "plot.window", "points", "rect", "text", "title") Modified: pkg/CHNOSZ/R/diagram.R =================================================================== --- pkg/CHNOSZ/R/diagram.R 2018-10-12 13:02:43 UTC (rev 333) +++ pkg/CHNOSZ/R/diagram.R 2018-10-30 02:55:56 UTC (rev 334) @@ -162,6 +162,7 @@ ## identify predominant species predominant <- NA + linesout <- NA if(plotvar %in% c("loga.equil", "alpha", "A/(2.303RT)") & type!="saturation") { pv <- plotvals # some additional steps for affinity values, but not for equilibrated activities @@ -469,7 +470,10 @@ } # the categories (species/groups/etc) on the plot zvals <- na.omit(unique(as.vector(predominant))) - # take each possible pair + # initialize list to output line coordinates + linesout <- list() + iout <- 1 + # take each possible pair of species for(i in 1:(length(zvals)-1)) { for(j in (i+1):length(zvals)) { z <- predominant @@ -478,9 +482,25 @@ # give them neighboring values (so we get one contour line) z[z==zvals[i]] <- 0 z[z==zvals[j]] <- 1 - contour(xs, ys, z, levels=0.5, drawlabels=FALSE, add=TRUE, lty=lty, col=col, lwd=lwd) + # use contourLines() instead of contour() in order to get line coordinates 20181029 + cLines <- contourLines(xs, ys, z, levels=0.5) + if(length(cLines) > 0) { + # loop in case contourLines returns multiple lines + for(k in 1:length(cLines)) { + # draw the lines + lines(cLines[[k]][2:3], lty=lty, col=col, lwd=lwd) + # keep the x and y values (list components 2 and 3) + linesout[[iout]] <- cLines[[k]][[2]] + names(linesout)[iout] <- paste0("x", k, "_", i, ".", j) + linesout[[iout+1]] <- cLines[[k]][[3]] + names(linesout)[iout+1] <- paste0("y", k, "_", i, ".", j) + iout <- iout + 2 + } + } } } + # https://stackoverflow.com/questions/34570860/adding-na-to-make-all-list-elements-equal-length 20181029 + lapply(linesout, `length<-`, max(lengths(linesout))) } ## label plot function # calculate coordinates for field labels @@ -577,7 +597,7 @@ # font metric state and subsequent errors adding e.g. subscripted text to plot) if(length(na.omit(unique(as.vector(zs)))) > 1) { if(!is.null(dotted)) plot.line(zs, xlim, ylim, dotted, col, lwd, xrange=xrange) - else contour.lines(predominant, xlim, ylim, lty=lty, col=col, lwd=lwd) + else linesout <- contour.lines(predominant, xlim, ylim, lty=lty, col=col, lwd=lwd) } # re-draw the tick marks and axis lines in case the fill obscured them if(tplot & !identical(fill, "transparent")) thermo.axis() @@ -585,8 +605,9 @@ out2D <- list(namesx=pn$namesx, namesy=pn$namesy, inames=pn$inames) } # end if(nd==2) } # end if(plot.it) - - out <- c(eout, list(plotvar=plotvar, plotvals=plotvals, names=names, predominant=predominant), out2D) + out <- c(eout, list(plotvar=plotvar, plotvals=plotvals, names=names, predominant=predominant)) + if(!identical(predominant, NA) & is.null(dotted)) out <- c(out, list(lines=linesout)) + out <- c(out, out2D) return(invisible(out)) } Modified: pkg/CHNOSZ/demo/affinity.R =================================================================== --- pkg/CHNOSZ/demo/affinity.R 2018-10-12 13:02:43 UTC (rev 333) +++ pkg/CHNOSZ/demo/affinity.R 2018-10-30 02:55:56 UTC (rev 334) @@ -77,7 +77,7 @@ # make a plot; set units to get correct label E.units("J") plot(out$Z.C, out$G.18, pch=20, xlim=c(-1.1, 1.1), ylim=c(-200, 500), - xlab=axis.label("ZC"), ylab=axis.label("DGr")) + xlab=axis.label("ZC"), ylab=axis.label("DGr", prefix="k")) points(out$Z.C, out$G.100, col="red", pch=20) legend("topleft", pch=c(20, 20), col=c("black", "red"), legend=describe.property(c("T", "T"), c(18, 100))) Modified: pkg/CHNOSZ/inst/NEWS =================================================================== --- pkg/CHNOSZ/inst/NEWS 2018-10-12 13:02:43 UTC (rev 333) +++ pkg/CHNOSZ/inst/NEWS 2018-10-30 02:55:56 UTC (rev 334) @@ -1,4 +1,4 @@ -CHANGES IN CHNOSZ 1.1.3-41 (2018-10-11) +CHANGES IN CHNOSZ 1.1.3-42 (2018-10-30) --------------------------------------- THERMODYNAMIC DATA @@ -75,6 +75,10 @@ formatted names (e.g. chemical formulas), and 'font' applies to those without formatting. +- 'lines' is added to the return list of diagram(), giving the + coordinates of lines (field boundaries) on 2-D diagrams (these are + taken from the output of contourLines()). + BUG FIXES - Fix a bug where subcrt()$reaction$coeffs was incorrect for reactions Modified: pkg/CHNOSZ/man/diagram.Rd =================================================================== --- pkg/CHNOSZ/man/diagram.Rd 2018-10-12 13:02:43 UTC (rev 333) +++ pkg/CHNOSZ/man/diagram.Rd 2018-10-30 02:55:56 UTC (rev 334) @@ -139,7 +139,7 @@ \code{fill.NA} is also used to specify the color outside the water stability limits on Eh-pH or pe-pH diagrams, when \code{limit.water} is TRUE. Note that the default for \code{fill.NA} is automatically changed to \samp{transparent} when \code{add} is TRUE. -The default line-drawing algorithm uses \code{\link{contour}} to draw smooth-looking diagonal and curved lines, at the expense of not coinciding exactly with the rectangular grid (which is still used for drawing colors). +The default line-drawing algorithm uses \code{\link{contourLines}} to obtain smooth-looking diagonal and curved lines, at the expense of not coinciding exactly with the rectangular grid that is used for drawing colors. \code{lty}, \code{col}, and \code{lwd} can be specified, but limiting the lines via \code{xrange} is not currently supported. To go back to the old behavior for drawing lines, set \code{dotted} to \samp{0}. The old behavior does not follow \code{lty}; instead, the style of the boundary lines on 2-D diagrams can be altered by supplying one or more non-zero integers in \code{dotted}, which indicates the fraction of line segments to omit; a value of \samp{1} or NULL for \code{dotted} has the effect of not drawing the boundary lines. @@ -159,7 +159,7 @@ If \code{type} is \samp{saturation}, the function plots the line for each species where the affinity of formation equals zero. If for a given species no saturation line is possible or the range of the diagram is beyond the saturation line, the function prints a message instead. If \code{type} is the name of a basis species, the equilibrium activity of the selected basis species in each of the formation reactions is plotted. -In the case of 2-D diagrams, both of these options use \code{\link{contour}} to draw the lines (see the \CO2-acetic acid example in \code{\link{buffer}}. +In the case of 2-D diagrams, both of these options use \code{\link{contour}} to draw the lines (see the \CO2-acetic acid example in \code{\link{buffer}}). The \samp{saturation} diagram can handle multiple species, but if \code{type} is the name a basis species, then only the first species of interest is used in the calculation, and a warning is produced if there is more than one. } @@ -183,9 +183,13 @@ This argument has the same format as \code{ispecies}, and can be used e.g. to display the relative numbers of species for comparison with the stability calculations. } -\value{ -For speciation diagrams (1-D), an \code{\link{invisible}} list of the chemical activities of the species, or their degrees of formation (if \code{alpha} is \code{TRUE}), at each point. -For predominance diagrams (2-D), an invisible list with elements \code{species}, the dataframe describing the species, \code{out}, which species predominates at each grid point, and \code{A}, a list of the calculated values of the chemical affinity (per balanced quantity) (log10 dimensionless) at each point. +\section{Value}{ + The function returns an \code{\link{invisible}} list containing, first, the contents of \code{eout}, i.e. the provided output of \code{\link{affinity}} or \code{\link{equilibrate}}. + To this are added the name of the plotted variable in \code{plotvar}, the plotted values in \code{plotvals}, and the names used for labeling the plot in \code{names}. + For 1-D diagrams, \code{plotvals} usually corresponds to the chemical activities of the species (i.e. \code{eout$loga.equil}), or, if \code{alpha} is \code{TRUE}, their mole fractions (degrees of formation). + For 2-D diagrams, the output also contains \code{predominant}, giving the numbers (from the \code{\link{species}} definition) of the predominant (aka maximum-affinity) species at each grid point. + The rows and columns of \code{predominant} correspond to the x- and y-variables, respectively. + Finally, the output for 2-D diagrams contains a \code{lines} component, giving the x- and y-coordinates of the field boundaries computed using \code{\link{contourLines}}; the values are padded to equal length with NAs to faciliate exporting the results using \code{\link{write.csv}}. } \seealso{ @@ -293,7 +297,7 @@ LaRowe, D. E. and Helgeson, H. C. (2007) Quantifying the energetics of metabolic reactions in diverse biogeochemical systems: electron flow and ATP synthesis. \emph{Geobiology} \bold{5}, 153--168. \url{https://doi.org/10.1111/j.1472-4669.2007.00099.x} - Majzlan, J., Navrotsky, A., McClesky, R. B. and Alpers, C. N. (2006) Thermodynamic properties and crystal structure refinement of ferricopiapite, coquimbite, rhomboclase, and Fe2(SO4)3(H2O)5. \emph{Eur. J. Mineral.} \bold{18}, 175--186. \url{https://doi.org/10.1127/0935-1221/2006/0018-0175} + Majzlan, J., Navrotsky, A., McClesky, R. B. and Alpers, C. N. (2006) Thermodynamic properties and crystal structure refinement of ferricopiapite, coquimbite, rhomboclase, and Fe\s{2}(SO\s{4})\s{3}(H\s{2}O)\s{5}. \emph{Eur. J. Mineral.} \bold{18}, 175--186. \url{https://doi.org/10.1127/0935-1221/2006/0018-0175} } \concept{Main workflow} Modified: pkg/CHNOSZ/man/macros/macros.Rd =================================================================== --- pkg/CHNOSZ/man/macros/macros.Rd 2018-10-12 13:02:43 UTC (rev 333) +++ pkg/CHNOSZ/man/macros/macros.Rd 2018-10-30 02:55:56 UTC (rev 334) @@ -17,6 +17,7 @@ \newcommand{\s2}{\ifelse{latex}{\eqn{_2}}{\ifelse{html}{\out{2}}{2}}} \newcommand{\s3}{\ifelse{latex}{\eqn{_3}}{\ifelse{html}{\out{3}}{3}}} \newcommand{\s4}{\ifelse{latex}{\eqn{_4}}{\ifelse{html}{\out{4}}{4}}} +\newcommand{\s}{\ifelse{latex}{\eqn{_{#1}}}{\ifelse{html}{\out{#1}}{#1}}} % superscript numbers \newcommand{\S}{\ifelse{latex}{\eqn{^{#1}}}{\ifelse{html}{\out{#1}}{^#1}}} From noreply at r-forge.r-project.org Tue Oct 30 14:57:03 2018 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Tue, 30 Oct 2018 14:57:03 +0100 (CET) Subject: [CHNOSZ-commits] r335 - in pkg/CHNOSZ: . R demo inst man Message-ID: <20181030135703.EC590180AAE@r-forge.r-project.org> Author: jedick Date: 2018-10-30 14:57:03 +0100 (Tue, 30 Oct 2018) New Revision: 335 Added: pkg/CHNOSZ/demo/oldsolub.R pkg/CHNOSZ/demo/solubility.R Removed: pkg/CHNOSZ/demo/solubility.R Modified: pkg/CHNOSZ/DESCRIPTION pkg/CHNOSZ/R/examples.R pkg/CHNOSZ/demo/00Index pkg/CHNOSZ/inst/NEWS pkg/CHNOSZ/man/examples.Rd Log: revise demo/solubility.R for vectorized calculation Modified: pkg/CHNOSZ/DESCRIPTION =================================================================== --- pkg/CHNOSZ/DESCRIPTION 2018-10-30 02:55:56 UTC (rev 334) +++ pkg/CHNOSZ/DESCRIPTION 2018-10-30 13:57:03 UTC (rev 335) @@ -1,6 +1,6 @@ Date: 2018-10-30 Package: CHNOSZ -Version: 1.1.3-42 +Version: 1.1.3-43 Title: Thermodynamic Calculations and Diagrams for Geo(bio)chemistry Authors at R: c( person("Jeffrey", "Dick", , "j3ffdick at gmail.com", role = c("aut", "cre"), Modified: pkg/CHNOSZ/R/examples.R =================================================================== --- pkg/CHNOSZ/R/examples.R 2018-10-30 02:55:56 UTC (rev 334) +++ pkg/CHNOSZ/R/examples.R 2018-10-30 13:57:03 UTC (rev 335) @@ -28,7 +28,7 @@ demos <- function(which=c("sources", "protein.equil", "affinity", "NaCl", "density", "ORP", "revisit", "findit", "ionize", "buffer", "protbuff", "yeastgfp", "mosaic", - "copper", "solubility", "wjd", "bugstab", "Shh", "activity_ratios", + "copper", "oldsolub", "solubility", "wjd", "bugstab", "Shh", "activity_ratios", "adenine", "DEW", "lambda", "TCA", "go-IU", "bison"), save.png=FALSE) { # run one or more demos from CHNOSZ with ask=FALSE, and return the value of the last one for(i in 1:length(which)) { Modified: pkg/CHNOSZ/demo/00Index =================================================================== --- pkg/CHNOSZ/demo/00Index 2018-10-30 02:55:56 UTC (rev 334) +++ pkg/CHNOSZ/demo/00Index 2018-10-30 13:57:03 UTC (rev 335) @@ -12,7 +12,8 @@ yeastgfp Subcellular locations: log fO2 - log aH2O and log a - log fO2 diagrams mosaic Eh-pH diagram for iron oxides, sulfides and carbonate with two sets of changing basis species copper Another example of mosaic(): complexation of copper with glycine species -solubility Solubility of calcite or CO2(gas) as a function of pH +oldsolub Old solubility calculations using uniroot() +solubility Solubility of calcite and CO2(gas) as a function of pH wjd Gibbs energy minimization: prebiological atmospheres and cell periphery of yeast dehydration log K of dehydration reactions; SVG file contains tooltips and links bugstab Formation potential of microbial proteins in colorectal cancer Copied: pkg/CHNOSZ/demo/oldsolub.R (from rev 334, pkg/CHNOSZ/demo/solubility.R) =================================================================== --- pkg/CHNOSZ/demo/oldsolub.R (rev 0) +++ pkg/CHNOSZ/demo/oldsolub.R 2018-10-30 13:57:03 UTC (rev 335) @@ -0,0 +1,87 @@ +# CHNOSZ/demo/oldsolub.R +# 20150306 added to CHNOSZ as solubility.R +# 20181030 renamed to oldsolub.R + +# demo showing how to calculate CO2(gas) or calcite solubility and aqueous carbonate speciation +# the affinity() ... equilibrate() sequence in CHNOSZ gives *metastable equilibrium activities* +# (activities for a total activity of the balanced component given in loga.balance) ... +# here we are interested in finding the value of loga.balance itself +# (the total activity of [CO2, HCO3-, CO3-2] species in the aqueous phase). +# this total activity is the solubility of CO2(gas) or calcite if the affinities of the +# aqueous species as formed from CO2(gas) or calcite are all equal to zero. +# note that the affinities for species in metastable equilibrium are all equal. +# Afun() calculates the metastable equilibrium affinities for a given loga.balance +# and uniroot() finds the loga.balance where they are zero +# additionally, if we are reacting calcite, the activity of Ca+2 should be set equal to loga.balance + +# for comparison with published calcite solubility plot, see Fig. 4A in +# Manning et al., 2013, Reviews in Mineralogy & Geochemistry, v. 75, pp. 109-148 +# (doi: 10.2138/rmg.2013.75.5) + +# for comparison with published CO2 solubility plot, see Fig. 4.5 in +# Stumm and Morgan, 1996, Aquatic Chemistry: Chemical Equilibria and Rates in Natural Waters +# (New York: John Wiley & Sons), 3rd edition + +# set this to CO2 or calcite +what <- "calcite" +#what <- "CO2" + +# function to return the affinity of the metastable equilibrium species +Afun <- function(loga.balance=-3, T=25) { + if(what=="calcite") basis("Ca+2", loga.balance) + a <- affinity(T=T) + e <- equilibrate(a, loga.balance=loga.balance) + # set metastable activities and re-calculate the affinity + species(1:3, unlist(e$loga.equil)) + a <- affinity(T=T) + # check they're actually equal + stopifnot(all(abs(unlist(a$values) - as.vector(a$values[[1]])) < 1e-10)) + return(a$values[[1]]) +} + +# set up system +if(what=="CO2") { + basis("CHNOS+") + basis("CO2", "gas") + # ca. atmospheric PCO2 + basis("CO2", -3.5) +} else if(what=="calcite") { + basis(c("calcite", "Ca+2", "H2O", "O2", "H+")) +} +species(c("CO2", "HCO3-", "CO3-2")) +T <- 25 +# decrease this for higher resolution +pHstep <- 1 + +# where we'll store the results +loga.tot <- numeric() +loga.CO2 <- loga.HCO3 <- loga.CO3 <- numeric() + +# loop over pH range +pHs <- seq(0, 14, pHstep) +for(pH in pHs) { + print(paste("pH =", pH)) + basis("pH", pH) + # this is for the solubility + loga.balance <- suppressMessages(uniroot(Afun, c(-10, 10), T=T)$root) + loga.tot <- c(loga.tot, loga.balance) + # this is for the speciation + if(what=="calcite") basis("Ca+2", loga.balance) + a <- affinity(T=T) + e <- equilibrate(a, loga.balance=loga.balance) + loga <- unlist(e$loga.equil) + loga.CO2 <- c(loga.CO2, loga[1]) + loga.HCO3 <- c(loga.HCO3, loga[2]) + loga.CO3 <- c(loga.CO3, loga[3]) +} + +# make plot +ylim <- c(-10, 4) +thermo.plot.new(xlim=range(pHs), ylim=ylim, xlab="pH", ylab="log a") +lines(pHs, loga.tot, lwd=4, col="green2") +lines(pHs, loga.CO2, lwd=2) +lines(pHs, loga.HCO3, lty=2, lwd=2) +lines(pHs, loga.CO3, lty=3, lwd=2) +legend(ifelse(what=="calcite", "topright", "topleft"), lty=c(1, 1:3), lwd=c(4, 2, 2, 2), col=c("green2", rep("black", 3)), + legend=as.expression(c("total", expr.species("CO2", state="aq"), expr.species("HCO3-"), expr.species("CO3-2")))) +title(main=substitute("Solubility of"~what~"at"~T~degree*"C", list(what=what, T=T))) Deleted: pkg/CHNOSZ/demo/solubility.R =================================================================== --- pkg/CHNOSZ/demo/solubility.R 2018-10-30 02:55:56 UTC (rev 334) +++ pkg/CHNOSZ/demo/solubility.R 2018-10-30 13:57:03 UTC (rev 335) @@ -1,83 +0,0 @@ -# demo showing how to calculate CO2(gas) or calcite solubility and aqueous carbonate speciation -# the affinity() ... equilibrate() sequence in CHNOSZ gives *metastable equilibrium activities* -# (activities for a total activity of the balanced component given in loga.balance) ... -# here we are interested in finding the value of loga.balance itself -# (the total activity of [CO2, HCO3-, CO3-2] species in the aqueous phase). -# this total activity is the solubility of CO2(gas) or calcite if the affinities of the -# aqueous species as formed from CO2(gas) or calcite are all equal to zero. -# note that the affinities for species in metastable equilibrium are all equal. -# Afun() calculates the metastable equilibrium affinities for a given loga.balance -# and uniroot() finds the loga.balance where they are zero -# additionally, if we are reacting calcite, the activity of Ca+2 should be set equal to loga.balance - -# for comparison with published calcite solubility plot, see Fig. 4A in -# Manning et al., 2013, Reviews in Mineralogy & Geochemistry, v. 75, pp. 109-148 -# (doi: 10.2138/rmg.2013.75.5) - -# for comparison with published CO2 solubility plot, see Fig. 4.5 in -# Stumm and Morgan, 1996, Aquatic Chemistry: Chemical Equilibria and Rates in Natural Waters -# (New York: John Wiley & Sons), 3rd edition - -# set this to CO2 or calcite -what <- "calcite" -#what <- "CO2" - -# function to return the affinity of the metastable equilibrium species -Afun <- function(loga.balance=-3, T=25) { - if(what=="calcite") basis("Ca+2", loga.balance) - a <- affinity(T=T) - e <- equilibrate(a, loga.balance=loga.balance) - # set metastable activities and re-calculate the affinity - species(1:3, unlist(e$loga.equil)) - a <- affinity(T=T) - # check they're actually equal - stopifnot(all(abs(unlist(a$values) - as.vector(a$values[[1]])) < 1e-10)) - return(a$values[[1]]) -} - -# set up system -if(what=="CO2") { - basis("CHNOS+") - basis("CO2", "gas") - # ca. atmospheric PCO2 - basis("CO2", -3.5) -} else if(what=="calcite") { - basis(c("calcite", "Ca+2", "H2O", "O2", "H+")) -} -species(c("CO2", "HCO3-", "CO3-2")) -T <- 25 -# decrease this for higher resolution -pHstep <- 1 - -# where we'll store the results -loga.tot <- numeric() -loga.CO2 <- loga.HCO3 <- loga.CO3 <- numeric() - -# loop over pH range -pHs <- seq(0, 14, pHstep) -for(pH in pHs) { - print(paste("pH =", pH)) - basis("pH", pH) - # this is for the solubility - loga.balance <- suppressMessages(uniroot(Afun, c(-10, 10), T=T)$root) - loga.tot <- c(loga.tot, loga.balance) - # this is for the speciation - if(what=="calcite") basis("Ca+2", loga.balance) - a <- affinity(T=T) - e <- equilibrate(a, loga.balance=loga.balance) - loga <- unlist(e$loga.equil) - loga.CO2 <- c(loga.CO2, loga[1]) - loga.HCO3 <- c(loga.HCO3, loga[2]) - loga.CO3 <- c(loga.CO3, loga[3]) -} - -# make plot -ylim <- c(-10, 4) -thermo.plot.new(xlim=range(pHs), ylim=ylim, xlab="pH", ylab="log a") -lines(pHs, loga.tot, lwd=4, col="green2") -lines(pHs, loga.CO2, lwd=2) -lines(pHs, loga.HCO3, lty=2, lwd=2) -lines(pHs, loga.CO3, lty=3, lwd=2) -legend(ifelse(what=="calcite", "topright", "topleft"), lty=c(1, 1:3), lwd=c(4, 2, 2, 2), col=c("green2", rep("black", 3)), - legend=as.expression(c("total", expr.species("CO2", state="aq"), expr.species("HCO3-"), expr.species("CO3-2")))) -title(main=substitute("Solubility of"~what~"at"~T~degree*"C", list(what=what, T=T))) Added: pkg/CHNOSZ/demo/solubility.R =================================================================== --- pkg/CHNOSZ/demo/solubility.R (rev 0) +++ pkg/CHNOSZ/demo/solubility.R 2018-10-30 13:57:03 UTC (rev 335) @@ -0,0 +1,86 @@ +# CHNOSZ/demo/solubility.R: vectorized solubility without uniroot +# adapted from CHNOSZ/demo/oldsolub.R +# 20181030 jmd + +# for comparison with published calcite solubility plot, see Fig. 4A in +# Manning et al., 2013, Reviews in Mineralogy & Geochemistry, v. 75, pp. 109-148 +# (doi: 10.2138/rmg.2013.75.5) + +# for comparison with published CO2 solubility plot, see Fig. 4.5 in +# Stumm and Morgan, 1996, Aquatic Chemistry: Chemical Equilibria and Rates in Natural Waters +# (New York: John Wiley & Sons), 3rd edition + +par(mfrow=c(1, 2)) + +for(what in c("CO2", "calcite")) { + + # set up system + if(what=="CO2") { + basis("CHNOS+") + basis("CO2", "gas") + # ca. atmospheric PCO2 + basis("CO2", -3.5) + } else if(what=="calcite") { + basis(c("calcite", "Ca+2", "H2O", "O2", "H+")) + } + species(c("CO2", "HCO3-", "CO3-2")) + + # set pH range and resolution, constant temperature and ionic strength + pH <- c(0, 14) + res <- 100 + T <- 25 + IS <- 0 + + # start with loga.balance = 0 + loga.balance <- 0 + a0 <- affinity(pH = c(pH, res), T = T, IS = IS) + e0 <- equilibrate(a0, loga.balance = loga.balance) + + # bookkeeping: track any single species + itrack <- 1 + # the log activity used to calculate the affinity + loga.species.track <- species(itrack)$logact + # the affinities at the starting loga.balance + A.track <- a0$values[[itrack]] + # the loga.equil at the starting loga.balance + loga.equil.track <- e0$loga.equil[[itrack]] + + # subjunctive: what would the affinities be if the + # activity of the tracked species was set to loga.equil? + A.whatif <- loga.species.track + A.track - loga.equil.track + + # predictive: assuming the species distribution doesn't change, + # what is the total loga that would give zero affinity? + # TODO: modify this according to stoichiometry (species with > 1 of the balanced basis species) + loga.total <- loga.balance + A.whatif + + # a dissociation reaction makes two things, so the exponent is not 1 + if(what=="calcite") loga.total <- loga.total / 2 + + # use the predicted loga.total to re-calculate activities of species + e1 <- equilibrate(a0, loga.balance = loga.total) + +# # check that we got stable conditions +# # (not easily vectorized because we change the activities of species) +# print("checking for stable conditions (affinity = 0)") +# for(i in 1:length(a0$vals[[1]])) { +# basis(a0$vars[1], a0$vals[[1]][i]) +# if(what=="calcite") basis("Ca+2", loga.total[i]) +# species(1:3, sapply(e1$loga.equil, "[", i)) +# atest <- suppressMessages(affinity(T = T, IS = IS)) +# stopifnot(all(sapply(as.numeric(unlist(atest$values)), all.equal, 0))) +# } + + # make plot + ylim <- c(-10, 4) + thermo.plot.new(xlim = range(pH), ylim = ylim, xlab = "pH", ylab = "log a") + lines(a0$vals[[1]], loga.total, lwd = 4, col = "green2") + lines(a0$vals[[1]], e1$loga.equil[[1]], lwd = 2) + lines(a0$vals[[1]], e1$loga.equil[[2]], lty = 2, lwd = 2) + lines(a0$vals[[1]], e1$loga.equil[[3]], lty = 3, lwd = 2) + + legend(ifelse(what=="calcite", "topright", "topleft"), lty = c(1, 1:3), lwd = c(4, 2, 2, 2), col = c("green2", rep("black", 3)), + legend = as.expression(c("total", expr.species("CO2", state = "aq"), expr.species("HCO3-"), expr.species("CO3-2")))) + title(main = substitute("Solubility of"~what~"at"~T~degree*"C", list(what = what, T = T))) + +} Modified: pkg/CHNOSZ/inst/NEWS =================================================================== --- pkg/CHNOSZ/inst/NEWS 2018-10-30 02:55:56 UTC (rev 334) +++ pkg/CHNOSZ/inst/NEWS 2018-10-30 13:57:03 UTC (rev 335) @@ -1,4 +1,4 @@ -CHANGES IN CHNOSZ 1.1.3-42 (2018-10-30) +CHANGES IN CHNOSZ 1.1.3-43 (2018-10-30) --------------------------------------- THERMODYNAMIC DATA @@ -135,6 +135,10 @@ duplicated references (but not including any secondary references in thermo$obigt$ref2). Thanks to Evgeniy Bastrakov for the suggestion. +- Revise demo/solubility.R to perform vectorized, direct solubility + calculations. The old demo that uses uniroot() has been moved to + demo/oldsolub.R. + CHANGES IN CHNOSZ 1.1.3 (2017-11-13) ------------------------------------ Modified: pkg/CHNOSZ/man/examples.Rd =================================================================== --- pkg/CHNOSZ/man/examples.Rd 2018-10-30 02:55:56 UTC (rev 334) +++ pkg/CHNOSZ/man/examples.Rd 2018-10-30 13:57:03 UTC (rev 335) @@ -15,9 +15,9 @@ examples(save.png = FALSE) demos(which = c("sources", "protein.equil", "affinity", "NaCl", "density", "ORP", "revisit", "findit", "ionize", "buffer", - "protbuff", "yeastgfp", "mosaic", "copper", "solubility", - "wjd", "bugstab", "Shh", "activity_ratios", "adenine", - "DEW", "lambda", "TCA", "go-IU", "bison"), + "protbuff", "yeastgfp", "mosaic", "copper", "oldsolub", + "solubility", "wjd", "bugstab", "Shh", "activity_ratios", + "adenine", "DEW", "lambda", "TCA", "go-IU", "bison"), save.png=FALSE) } @@ -45,7 +45,8 @@ \code{yeastgfp} \tab * Subcellular locations: \logfO2 - \logaH2O and \loga - \logfO2 diagrams (Dick, 2009) \cr \code{mosaic} \tab * Eh-pH diagram with two sets of changing basis species (Garrels and Christ, 1965) \cr \code{copper} \tab * Another example of \code{\link{mosaic}}: complexation of Cu with glycine (Aksu and Doyle, 2001) \cr - \code{solubility} \tab * Solubility of calcite (cf. Manning et al., 2013) or \CO2 (cf. Stumm and Morgan, 1996) \cr + \code{oldsolub} \tab Old solubility calculations using \code{\link{uniroot}} \cr + \code{solubility} \tab * Solubility of calcite (cf. Manning et al., 2013) and \CO2 (cf. Stumm and Morgan, 1996) \cr \code{wjd} \tab * \eqn{G}{G} minimization: prebiological atmospheres (Dayhoff et al., 1964) and cell periphery of yeast \cr \code{dehydration} \tab * \logK of dehydration reactions; SVG file contains tooltips and links \cr \code{bugstab} \tab * Formation potential of microbial proteins in colorectal cancer (Dick, 2016) \cr From noreply at r-forge.r-project.org Wed Oct 31 04:29:21 2018 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Wed, 31 Oct 2018 04:29:21 +0100 (CET) Subject: [CHNOSZ-commits] r336 - in pkg/CHNOSZ: . R demo tests/testthat vignettes Message-ID: <20181031032921.2A4E518B41A@r-forge.r-project.org> Author: jedick Date: 2018-10-31 04:29:20 +0100 (Wed, 31 Oct 2018) New Revision: 336 Modified: pkg/CHNOSZ/DESCRIPTION pkg/CHNOSZ/R/basis.R pkg/CHNOSZ/R/diagram.R pkg/CHNOSZ/R/equilibrate.R pkg/CHNOSZ/demo/solubility.R pkg/CHNOSZ/tests/testthat/test-basis.R pkg/CHNOSZ/tests/testthat/test-diagram.R pkg/CHNOSZ/tests/testthat/test-swap.basis.R pkg/CHNOSZ/vignettes/anintro.Rmd Log: equilibrate(): return name of balanced basis species, even if not specified in argument Modified: pkg/CHNOSZ/DESCRIPTION =================================================================== --- pkg/CHNOSZ/DESCRIPTION 2018-10-30 13:57:03 UTC (rev 335) +++ pkg/CHNOSZ/DESCRIPTION 2018-10-31 03:29:20 UTC (rev 336) @@ -1,6 +1,6 @@ -Date: 2018-10-30 +Date: 2018-10-31 Package: CHNOSZ -Version: 1.1.3-43 +Version: 1.1.3-44 Title: Thermodynamic Calculations and Diagrams for Geo(bio)chemistry Authors at R: c( person("Jeffrey", "Dick", , "j3ffdick at gmail.com", role = c("aut", "cre"), Modified: pkg/CHNOSZ/R/basis.R =================================================================== --- pkg/CHNOSZ/R/basis.R 2018-10-30 13:57:03 UTC (rev 335) +++ pkg/CHNOSZ/R/basis.R 2018-10-31 03:29:20 UTC (rev 336) @@ -109,8 +109,14 @@ if("(Z-1)" %in% rownames(comp)) rownames(comp)[rownames(comp)=="(Z-1)"] <- "e-" # now check it for validity of basis species # the first test: matrix is square - if( nrow(comp) > ncol(comp) ) stop("overdetermined system; square stoichiometric matrix needed") - if( nrow(comp) < ncol(comp) ) stop("underdetermined system; square stoichiometric matrix needed") + if( nrow(comp) > ncol(comp) ) { + if("Z" %in% colnames(comp)) stop("the number of basis species is greater than the number of elements and charge") + else stop("the number of basis species is greater than the number of elements") + } + if( nrow(comp) < ncol(comp) ) { + if("Z" %in% colnames(comp)) stop("the number of basis species is less than the number of elements and charge") + else stop("the number of basis species is less than the number of elements") + } # the second test: matrix is invertible if(class(try(solve(comp), silent=TRUE))=='try-error') stop("singular stoichiometric matrix") Modified: pkg/CHNOSZ/R/diagram.R =================================================================== --- pkg/CHNOSZ/R/diagram.R 2018-10-30 13:57:03 UTC (rev 335) +++ pkg/CHNOSZ/R/diagram.R 2018-10-31 03:29:20 UTC (rev 336) @@ -53,7 +53,7 @@ if(!"loga.equil" %in% names(eout)) { eout.is.aout <- TRUE # get the balancing coefficients - if(type=="auto") n.balance <- balance(eout, balance) + if(type=="auto") n.balance <- balance(eout, balance)$n.balance else n.balance <- rep(1, length(eout$values)) } } else if(type %in% rownames(eout$basis)) { Modified: pkg/CHNOSZ/R/equilibrate.R =================================================================== --- pkg/CHNOSZ/R/equilibrate.R 2018-10-30 13:57:03 UTC (rev 335) +++ pkg/CHNOSZ/R/equilibrate.R 2018-10-31 03:29:20 UTC (rev 336) @@ -15,7 +15,9 @@ ## number of possible species nspecies <- length(aout$values) ## get the balancing coefficients - n.balance <- balance(aout, balance) + bout <- balance(aout, balance) + n.balance <- bout$n.balance + balance <- bout$balance ## take selected species in 'ispecies' if(length(ispecies)==0) stop("the length of ispecies is zero") # take out species that have NA affinities @@ -249,7 +251,7 @@ ### unexported functions ### -# return a list containing the balancing coefficients (n) and a textual description (description) +# return a list containing the balancing coefficients (n.balance) and a textual description (balance) balance <- function(aout, balance=NULL) { ## generate n.balance from user-given or automatically identified basis species ## extracted from equilibrate() 20120929 @@ -302,5 +304,5 @@ if(any(n.balance==0)) stop("some species have no ", balance, " in the formation reaction") } } - return(n.balance) + return(list(n.balance=n.balance, balance=balance)) } Modified: pkg/CHNOSZ/demo/solubility.R =================================================================== --- pkg/CHNOSZ/demo/solubility.R 2018-10-30 13:57:03 UTC (rev 335) +++ pkg/CHNOSZ/demo/solubility.R 2018-10-31 03:29:20 UTC (rev 336) @@ -50,7 +50,7 @@ A.whatif <- loga.species.track + A.track - loga.equil.track # predictive: assuming the species distribution doesn't change, - # what is the total loga that would give zero affinity? + # what is the log(total activity) that gives zero affinity? # TODO: modify this according to stoichiometry (species with > 1 of the balanced basis species) loga.total <- loga.balance + A.whatif Modified: pkg/CHNOSZ/tests/testthat/test-basis.R =================================================================== --- pkg/CHNOSZ/tests/testthat/test-basis.R 2018-10-30 13:57:03 UTC (rev 335) +++ pkg/CHNOSZ/tests/testthat/test-basis.R 2018-10-31 03:29:20 UTC (rev 336) @@ -6,8 +6,8 @@ test_that("invalid basis definitions cause an error", { expect_error(basis(character()), "argument is empty") expect_error(basis(c("CO2", "CO2")), "names are not unique") - expect_error(basis(c("CO2", "H2O")), "underdetermined") - expect_error(basis(c("H2O", "O2", "H2")), "overdetermined") + expect_error(basis(c("CO2", "H2O")), "the number of basis species is less than the number of elements") + expect_error(basis(c("H2O", "O2", "H2")), "the number of basis species is greater than the number of elements") expect_error(basis(c("HCN", "H2O", "O2", "H2")), "singular") expect_error(basis(c("CN", "H2O", "O2", "H2")), "species not available") expect_error(basis(c("CN")), "species not available") Modified: pkg/CHNOSZ/tests/testthat/test-diagram.R =================================================================== --- pkg/CHNOSZ/tests/testthat/test-diagram.R 2018-10-30 13:57:03 UTC (rev 335) +++ pkg/CHNOSZ/tests/testthat/test-diagram.R 2018-10-31 03:29:20 UTC (rev 336) @@ -49,7 +49,7 @@ # group the species together d <- diagram(e, groups=list(1:2, 3:4), plot.it=FALSE) # we should find that their activities have been multiplied by the balance coefficients and summed - n.balance <- balance(a) + n.balance <- balance(a)$n.balance expect_equal(d$plotvals[[1]], log10(n.balance[1]*10^e$loga.equil[[1]] + n.balance[2]*10^e$loga.equil[[2]])) expect_equal(d$plotvals[[2]], log10(n.balance[3]*10^e$loga.equil[[3]] + n.balance[4]*10^e$loga.equil[[4]])) # ask for degrees of formation instead of logarithms of activities Modified: pkg/CHNOSZ/tests/testthat/test-swap.basis.R =================================================================== --- pkg/CHNOSZ/tests/testthat/test-swap.basis.R 2018-10-30 13:57:03 UTC (rev 335) +++ pkg/CHNOSZ/tests/testthat/test-swap.basis.R 2018-10-31 03:29:20 UTC (rev 336) @@ -10,7 +10,7 @@ expect_error(swap.basis(c("CO2", "H2O"), c("HCO3-", "H2O")), "can only swap one species for one species") expect_error(swap.basis("CH4", "C2H5OH"), "basis species .* is not defined") expect_error(swap.basis("CO2", "C60"), "is not available") - expect_error(swap.basis("CO2", "H2"), "overdetermined") + expect_error(swap.basis("CO2", "H2"), "the number of basis species is greater than the number of elements and charge") }) test_that("basis.logact only accepts defined elements", { Modified: pkg/CHNOSZ/vignettes/anintro.Rmd =================================================================== --- pkg/CHNOSZ/vignettes/anintro.Rmd 2018-10-30 13:57:03 UTC (rev 335) +++ pkg/CHNOSZ/vignettes/anintro.Rmd 2018-10-31 03:29:20 UTC (rev 336) @@ -924,7 +924,7 @@ The possible reactions between species are all balanced on 1 C. Therefore, although pH alters the total activity of C, in a system with ideal mixing the total activity of C doesn't affect the relative activities of these species. ```{marginfigure} -See [`demo(solubility)`](../demo) for calculations of the total activity of C in this ideal system; uncomment a line in the demo to run calculations for CO2 instead of calcite. +See [`demo(solubility)`](../demo) for calculations of the total activity of C in equilibrium with either CO2(gas) or calcite. ``` ## Groups of species From noreply at r-forge.r-project.org Wed Oct 31 07:25:36 2018 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Wed, 31 Oct 2018 07:25:36 +0100 (CET) Subject: [CHNOSZ-commits] r337 - in pkg/CHNOSZ: . R demo inst man tests/testthat vignettes Message-ID: <20181031062536.E5DC718A394@r-forge.r-project.org> Author: jedick Date: 2018-10-31 07:25:35 +0100 (Wed, 31 Oct 2018) New Revision: 337 Added: pkg/CHNOSZ/R/solubility.R pkg/CHNOSZ/man/solubility.Rd pkg/CHNOSZ/tests/testthat/test-solubility.R Modified: pkg/CHNOSZ/DESCRIPTION pkg/CHNOSZ/NAMESPACE pkg/CHNOSZ/R/diagram.R pkg/CHNOSZ/demo/solubility.R pkg/CHNOSZ/inst/NEWS pkg/CHNOSZ/man/nonideal.Rd pkg/CHNOSZ/vignettes/anintro.Rmd Log: add solubility() function, test, and expanded demo Modified: pkg/CHNOSZ/DESCRIPTION =================================================================== --- pkg/CHNOSZ/DESCRIPTION 2018-10-31 03:29:20 UTC (rev 336) +++ pkg/CHNOSZ/DESCRIPTION 2018-10-31 06:25:35 UTC (rev 337) @@ -1,6 +1,6 @@ Date: 2018-10-31 Package: CHNOSZ -Version: 1.1.3-44 +Version: 1.1.3-45 Title: Thermodynamic Calculations and Diagrams for Geo(bio)chemistry Authors at R: c( person("Jeffrey", "Dick", , "j3ffdick at gmail.com", role = c("aut", "cre"), Modified: pkg/CHNOSZ/NAMESPACE =================================================================== --- pkg/CHNOSZ/NAMESPACE 2018-10-31 03:29:20 UTC (rev 336) +++ pkg/CHNOSZ/NAMESPACE 2018-10-31 06:25:35 UTC (rev 337) @@ -56,7 +56,7 @@ "calculateEpsilon", "calculateQ", "water.DEW", "berman", "maxdiff", "expect_maxdiff", "Bdot", # added 20171121 or later - "dumpdata", "thermo.axis" + "dumpdata", "thermo.axis", "solubility" ) # Load shared objects Modified: pkg/CHNOSZ/R/diagram.R =================================================================== --- pkg/CHNOSZ/R/diagram.R 2018-10-31 03:29:20 UTC (rev 336) +++ pkg/CHNOSZ/R/diagram.R 2018-10-31 06:25:35 UTC (rev 337) @@ -47,6 +47,7 @@ # 'loga.equil' - equilibrium activities of species of interest (eout) # name of basis species - equilibrium activity of a basis species (aout) # 'saturation' - affinity=0 line for each species (2D) + # 'loga.balance' - activity of balanced basis species (eout from solubility()) eout.is.aout <- FALSE plot.loga.basis <- FALSE if(type %in% c("auto", "saturation")) { @@ -62,7 +63,7 @@ if(isTRUE(alpha) | is.character(alpha)) stop("equilibrium activities of basis species not available with alpha=TRUE") plot.loga.basis <- TRUE } else if(type=="loga.equil" & !"loga.equil" %in% names(eout)) stop("'eout' is not the output from equil()") - else if(type!="loga.equil") stop(type, " is not a valid diagram type") + else if(!type %in% c("loga.equil", "loga.balance")) stop(type, " is not a valid diagram type") ## consider a different number of species if we're grouping them together ngroups <- length(groups) @@ -72,6 +73,12 @@ plotvals <- eout$loga.equil plotvar <- "loga.equil" + ## handle loga.balance here (i.e. solubility calculations) + if(type=="loga.balance") { + plotvals <- list(eout$loga.balance) + plotvar <- "loga.balance" + } + ## number of dimensions (T, P or chemical potentials that are varied) # length(eout$vars) - the number of variables = the maximum number of dimensions # length(dim(eout$values[[1]])) - nd=1 if it was a transect along multiple variables @@ -209,7 +216,10 @@ ### general plot parameters ### ## handle line type/width/color arguments - if(is.null(lty)) lty <- 1:ngroups + if(is.null(lty)) { + if(type=="loga.balance") lty <- 1 + else lty <- 1:ngroups + } lty <- rep(lty, length.out=ngroups) lwd <- rep(lwd, length.out=ngroups) col <- rep(col, length.out=ngroups) @@ -302,7 +312,7 @@ lines(spline.x, spline.y, col=col[i], lty=lty[i], lwd=lwd[i]) } } - if(!add & !is.null(legend.x)) { + if(type %in% c("auto", "loga.equil") & !is.null(legend.x)) { # 20120521: use legend.x=NA to label lines rather than make legend if(is.na(legend.x)) { maxvals <- do.call(pmax, pv) @@ -581,7 +591,7 @@ else contour(xs, ys, zs, add=TRUE, col=col, lty=lty, lwd=lwd, labcex=cex, levels=0, labels=names[i], method=contour.method) } } else { - # otherwise, make contours of properties using first species only + # contour solubilities (loga.balance), or properties using first species only if(length(plotvals) > 1) warning("showing only first species in 2-D property diagram") zs <- plotvals[[1]] contour(xs, ys, zs, add=TRUE, col=col, lty=lty, lwd=lwd, labcex=cex, method=contour.method) Added: pkg/CHNOSZ/R/solubility.R =================================================================== --- pkg/CHNOSZ/R/solubility.R (rev 0) +++ pkg/CHNOSZ/R/solubility.R 2018-10-31 06:25:35 UTC (rev 337) @@ -0,0 +1,32 @@ +# solubility.R: vectorized solubility calculations without uniroot +# 20181031 jmd + +solubility <- function(eout, exp = 1) { + # exp = 1: e.g. dissolution of CO2 + # exp = 2: e.g. dissolution (dissociation) of CaCO3 + + # bookkeeping: track any single species + itrack <- 1 + # the log activity used to calculate the affinity + loga.species.track <- eout$species$logact[itrack] + # the affinities at the starting loga.balance + A.track <- eout$values[[itrack]] + # the loga.equil at the starting loga.balance + loga.equil.track <- eout$loga.equil[[itrack]] + + # subjunctive: what would the affinities be if the + # activity of the tracked species was set to loga.equil? + A.whatif <- loga.species.track + A.track - loga.equil.track + + # predictive: assuming the species distribution doesn't change, + # what is the total loga that would give zero affinity? + # TODO: modify this according to stoichiometry (species with > 1 of the balanced basis species) + loga.total <- (eout$loga.balance + A.whatif) / exp + + message("solubility: calculated logarithm of total activity of ", eout$balance) + + # use the predicted loga.total to re-calculate activities of species + aout <- eout[1:which(names(eout)=="values")] + equilibrate(aout, loga.balance = loga.total) +} + Modified: pkg/CHNOSZ/demo/solubility.R =================================================================== --- pkg/CHNOSZ/demo/solubility.R 2018-10-31 03:29:20 UTC (rev 336) +++ pkg/CHNOSZ/demo/solubility.R 2018-10-31 06:25:35 UTC (rev 337) @@ -1,86 +1,69 @@ # CHNOSZ/demo/solubility.R: vectorized solubility without uniroot -# adapted from CHNOSZ/demo/oldsolub.R -# 20181030 jmd +# 20181030 adapted from CHNOSZ/demo/oldsolub.R +# 20181031 use new solubility(); add T-pH plots -# for comparison with published calcite solubility plot, see Fig. 4A in -# Manning et al., 2013, Reviews in Mineralogy & Geochemistry, v. 75, pp. 109-148 -# (doi: 10.2138/rmg.2013.75.5) - # for comparison with published CO2 solubility plot, see Fig. 4.5 in # Stumm and Morgan, 1996, Aquatic Chemistry: Chemical Equilibria and Rates in Natural Waters # (New York: John Wiley & Sons), 3rd edition -par(mfrow=c(1, 2)) +# for comparison with published calcite solubility plot, see Fig. 4A in +# Manning et al., 2013, Reviews in Mineralogy & Geochemistry, v. 75, pp. 109-148 +# (doi: 10.2138/rmg.2013.75.5) -for(what in c("CO2", "calcite")) { +layout(matrix(1:4, nrow = 2)) - # set up system - if(what=="CO2") { - basis("CHNOS+") - basis("CO2", "gas") - # ca. atmospheric PCO2 - basis("CO2", -3.5) - } else if(what=="calcite") { - basis(c("calcite", "Ca+2", "H2O", "O2", "H+")) - } - species(c("CO2", "HCO3-", "CO3-2")) +# set pH and T range and resolution, constant temperature and ionic strength +pH <- c(0, 14) +T <- c(0, 300) +res <- 100 +T1 <- 25 +IS <- 0 - # set pH range and resolution, constant temperature and ionic strength - pH <- c(0, 14) - res <- 100 - T <- 25 - IS <- 0 +# start with CO2 +basis(c("carbon dioxide", "H2O", "O2", "H+")) +# ca. atmospheric PCO2 +basis("CO2", -3.5) +species(c("CO2", "HCO3-", "CO3-2")) +a <- affinity(pH = c(pH, res), T = T1, IS = IS) +e <- equilibrate(a) +s <- solubility(e) +# first plot total activity line +diagram(s, ylim = c(-10, 4), type = "loga.balance", lwd = 4, col = "green2") +# add activities of species +diagram(s, ylim=c(-10, 4), add = TRUE, dy = 1) +# add legend +lexpr <- as.expression(c("total", expr.species("CO2", state = "aq"), + expr.species("HCO3-"), expr.species("CO3-2"))) +legend("topleft", lty = c(1, 1:3), lwd = c(4, 2, 2, 2), + col = c("green2", rep("black", 3)), legend = lexpr) +title(main = substitute("Solubility of"~what~"at"~T~degree*"C", + list(what = expr.species("CO2"), T = T1)), line = 1.6) +mtext("cf. Fig. 4.5 of Stumm and Morgan, 1996") - # start with loga.balance = 0 - loga.balance <- 0 - a0 <- affinity(pH = c(pH, res), T = T, IS = IS) - e0 <- equilibrate(a0, loga.balance = loga.balance) +# CO2 T-pH plot +a <- affinity(pH = c(pH, res), T = c(T, res), IS = IS) +e <- equilibrate(a) +s <- solubility(e) +diagram(s, type = "loga.balance") +title(main = substitute("Solubility of"~what, list(what = expr.species("CO2")))) - # bookkeeping: track any single species - itrack <- 1 - # the log activity used to calculate the affinity - loga.species.track <- species(itrack)$logact - # the affinities at the starting loga.balance - A.track <- a0$values[[itrack]] - # the loga.equil at the starting loga.balance - loga.equil.track <- e0$loga.equil[[itrack]] +# now do calcite +basis(c("calcite", "Ca+2", "H2O", "O2", "H+")) +species(c("CO2", "HCO3-", "CO3-2")) +a <- affinity(pH = c(pH, res), T = T1, IS = IS) +e <- equilibrate(a) +s <- solubility(e, exp = 2) +diagram(s, ylim = c(-10, 4), type = "loga.balance", lwd = 4, col = "green2") +diagram(s, add = TRUE, dy = 1) +legend("topright", lty = c(1, 1:3), lwd = c(4, 2, 2, 2), + col = c("green2", rep("black", 3)), legend = lexpr) +title(main = substitute("Solubility of"~what~"at"~T~degree*"C", + list(what = "calcite", T = T1)), line = 1.6) +mtext("cf. Fig. 4A of Manning et al., 2013") - # subjunctive: what would the affinities be if the - # activity of the tracked species was set to loga.equil? - A.whatif <- loga.species.track + A.track - loga.equil.track - - # predictive: assuming the species distribution doesn't change, - # what is the log(total activity) that gives zero affinity? - # TODO: modify this according to stoichiometry (species with > 1 of the balanced basis species) - loga.total <- loga.balance + A.whatif - - # a dissociation reaction makes two things, so the exponent is not 1 - if(what=="calcite") loga.total <- loga.total / 2 - - # use the predicted loga.total to re-calculate activities of species - e1 <- equilibrate(a0, loga.balance = loga.total) - -# # check that we got stable conditions -# # (not easily vectorized because we change the activities of species) -# print("checking for stable conditions (affinity = 0)") -# for(i in 1:length(a0$vals[[1]])) { -# basis(a0$vars[1], a0$vals[[1]][i]) -# if(what=="calcite") basis("Ca+2", loga.total[i]) -# species(1:3, sapply(e1$loga.equil, "[", i)) -# atest <- suppressMessages(affinity(T = T, IS = IS)) -# stopifnot(all(sapply(as.numeric(unlist(atest$values)), all.equal, 0))) -# } - - # make plot - ylim <- c(-10, 4) - thermo.plot.new(xlim = range(pH), ylim = ylim, xlab = "pH", ylab = "log a") - lines(a0$vals[[1]], loga.total, lwd = 4, col = "green2") - lines(a0$vals[[1]], e1$loga.equil[[1]], lwd = 2) - lines(a0$vals[[1]], e1$loga.equil[[2]], lty = 2, lwd = 2) - lines(a0$vals[[1]], e1$loga.equil[[3]], lty = 3, lwd = 2) - - legend(ifelse(what=="calcite", "topright", "topleft"), lty = c(1, 1:3), lwd = c(4, 2, 2, 2), col = c("green2", rep("black", 3)), - legend = as.expression(c("total", expr.species("CO2", state = "aq"), expr.species("HCO3-"), expr.species("CO3-2")))) - title(main = substitute("Solubility of"~what~"at"~T~degree*"C", list(what = what, T = T))) - -} +# calcite T-pH plot +a <- affinity(pH = c(pH, res), T = c(T, res), IS = IS) +e <- equilibrate(a) +s <- solubility(e, exp = 2) +diagram(s, type = "loga.balance") +title(main = "Solubility of calcite", font.main = 1) Modified: pkg/CHNOSZ/inst/NEWS =================================================================== --- pkg/CHNOSZ/inst/NEWS 2018-10-31 03:29:20 UTC (rev 336) +++ pkg/CHNOSZ/inst/NEWS 2018-10-31 06:25:35 UTC (rev 337) @@ -1,6 +1,17 @@ -CHANGES IN CHNOSZ 1.1.3-43 (2018-10-30) +CHANGES IN CHNOSZ 1.1.3-45 (2018-10-31) --------------------------------------- +NEW FEATURES + +- Add solubility(). Run this after equilibrate() to calculate the + solubility (loga.balance) of the balanced basis species. + +- Revise demo/solubility.R to show solubility calculations for CO2(gas) + and calcite as a function of T and pH. + +- The old solubility demo, which uses uniroot() instead of the + vectorized calculations in solubility(), has been renamed oldsolub.R. + THERMODYNAMIC DATA - The Berman data (Berman, 1988 and later additions) have replaced the @@ -135,10 +146,6 @@ duplicated references (but not including any secondary references in thermo$obigt$ref2). Thanks to Evgeniy Bastrakov for the suggestion. -- Revise demo/solubility.R to perform vectorized, direct solubility - calculations. The old demo that uses uniroot() has been moved to - demo/oldsolub.R. - CHANGES IN CHNOSZ 1.1.3 (2017-11-13) ------------------------------------ Modified: pkg/CHNOSZ/man/nonideal.Rd =================================================================== --- pkg/CHNOSZ/man/nonideal.Rd 2018-10-31 03:29:20 UTC (rev 336) +++ pkg/CHNOSZ/man/nonideal.Rd 2018-10-31 06:25:35 UTC (rev 337) @@ -117,7 +117,7 @@ a <- affinity(IS=c(0, 0.14), T=T) e <- equilibrate(a) if(T==25) diagram(e, ylim=c(-3.0, -2.6), legend.x=NULL) - else diagram(e, ylim=c(-3.0, -2.6), add=TRUE, col="red") + else diagram(e, add=TRUE, names=NULL, col="red") } title(main="Non-ideality model for phosphate species") dp <- describe.property(c("pH", "T", "T"), c(7, Ts)) Added: pkg/CHNOSZ/man/solubility.Rd =================================================================== --- pkg/CHNOSZ/man/solubility.Rd (rev 0) +++ pkg/CHNOSZ/man/solubility.Rd 2018-10-31 06:25:35 UTC (rev 337) @@ -0,0 +1,86 @@ +\encoding{UTF-8} +\name{solubility} +\alias{solubility} +\title{Equilibrium Chemical Activities of Species} +\description{ +Calculate chemical activities of species in equilibrium with a soluble basis species. +} + +\usage{ + solubility(eout, exp = 1) +} + +\arguments{ + \item{eout}{list, output from \code{\link{equilibrate}}} + \item{exp}{numeric, exponent characterizing the stoichiometry of the dissociation reaction} +} + +\details{ +Use this function to calculate solubilities of minerals (such as CaCO\s3) or gases (such as CO\s2). +Start by using \code{\link{equilibrate}} to calculate equilibrium chemical activities of species given a constant value of \code{loga.balance} (the logarithm of total activity of the balanced basis species). +Note that this produces affinities of formation reactions of species that are equal to each other, but are generally not equal to zero. +\code{solubility} adjusts \code{loga.balance} such that the affinities of the formation reaction become zero. +This corresponds to \dQuote{true} equilibrium for a solution in contact with the balanced basis species - i.e. the solubility of that species. + +Normally, the balance is automatically identified as the first basis species that is present in all of the species. +If that is not adequate, it can be explicitly set via the \samp{balance} setting in \code{equilibrate}. + +The value of \code{exp} should be changed when calculating solubility of species that dissociate (not just dissolve). +For example, set \code{exp} to 2 for calculating the solubility of calcite (CaCO\s3). + +The output of \code{solubility} has the same format as that of \code{equilibrate}, and can be used by \code{\link{diagram}} with \code{type = "loga.balance"}. +} + +\examples{\dontshow{data(thermo)} +# solubility of CO2 and calcite as a function of pH +par(mfrow = c(1, 2)) + +# set pH range and resolution, constant temperature and ionic strength +pH <- c(0, 14) +res <- 100 +T <- 25 +IS <- 0 + +# start with CO2 +basis(c("carbon dioxide", "H2O", "O2", "H+")) +# ca. atmospheric PCO2 +basis("CO2", -3.5) +species(c("CO2", "HCO3-", "CO3-2")) +a <- affinity(pH = c(pH, res), T = T, IS = IS) +e <- equilibrate(a) +s <- solubility(e) +# first plot total activity line +diagram(s, ylim = c(-10, 4), type = "loga.balance", lwd = 4, col = "green2") +# add activities of species +diagram(s, ylim=c(-10, 4), add = TRUE, dy = 1) +# add legend +lexpr <- as.expression(c("total", expr.species("CO2", state = "aq"), + expr.species("HCO3-"), expr.species("CO3-2"))) +legend("topleft", lty = c(1, 1:3), lwd = c(4, 2, 2, 2), + col = c("green2", rep("black", 3)), legend = lexpr) +title(main = substitute("Solubility of"~what~"at"~T~degree*"C", + list(what = expr.species("CO2"), T = T)), line = 1.5) +mtext("cf. Fig. 4.5 of Stumm and Morgan, 1996") + +# now do calcite +basis(c("calcite", "Ca+2", "H2O", "O2", "H+")) +species(c("CO2", "HCO3-", "CO3-2")) +a <- affinity(pH = c(pH, res), T = T, IS = IS) +e <- equilibrate(a) +s <- solubility(e, exp = 2) +diagram(s, ylim = c(-10, 4), type = "loga.balance", lwd = 4, col = "green2") +diagram(s, add = TRUE, dy = 1) +legend("topright", lty = c(1, 1:3), lwd = c(4, 2, 2, 2), + col = c("green2", rep("black", 3)), legend = lexpr) +title(main = substitute("Solubility of"~what~"at"~T~degree*"C", + list(what = "calcite", T = T))) +mtext("cf. Fig. 4A of Manning et al., 2013") +} + +\references{ +Manning, C. E., Shock, E. L. and Sverjensky, D. A. (2013) The chemistry of carbon in aqueous fluids at crustal and upper-mantle conditions: Experimental and theoretical constraints. \emph{Rev. Mineral. Geochem.} \bold{75}, 109--148. \url{https://doi.org/10.2138/rmg.2013.75.5} + +Stumm, W. and Morgan, J. J. (1996) \emph{Aquatic Chemistry: Chemical Equilibria and Rates in Natural Waters}, John Wiley & Sons, New York, 1040 p. \url{http://www.worldcat.org/oclc/31754493} +} + +\concept{Main workflow} Added: pkg/CHNOSZ/tests/testthat/test-solubility.R =================================================================== --- pkg/CHNOSZ/tests/testthat/test-solubility.R (rev 0) +++ pkg/CHNOSZ/tests/testthat/test-solubility.R 2018-10-31 06:25:35 UTC (rev 337) @@ -0,0 +1,35 @@ +context("solubility") + +test_that("solubility() produces stable conditions (affinity = 0)", { + # set pH range and resolution, constant temperature and ionic strength + pH <- c(0, 14) + res <- 100 + T <- 25 + IS <- 0 + + # start with CO2 + basis(c("carbon dioxide", "H2O", "O2", "H+")) + # ca. atmospheric PCO2 + basis("CO2", -3.5) + species(c("CO2", "HCO3-", "CO3-2")) + a <- affinity(pH = c(pH, res), T = T, IS = IS) + e <- equilibrate(a) + s <- solubility(e) + + # check for stable conditions (affinity = 0) + species(1:3, 0) + atest <- affinity(pH = s$vals[[1]], T = T, IS = IS) + expect_true(all(sapply(unlist(atest$values) - unlist(s$loga.equil), all.equal, 0))) + + # now do calcite + basis(c("calcite", "Ca+2", "H2O", "O2", "H+")) + species(c("CO2", "HCO3-", "CO3-2")) + a <- affinity(pH = c(pH, res), T = T, IS = IS) + e <- equilibrate(a) + s <- solubility(e, exp = 2) + + # check for stable conditions (affinity = 0) + species(1:3, 0) + atest <- affinity(pH = s$vals[[1]], `Ca+2` = s$loga.balance, T = T, IS = IS) + expect_true(all(sapply(unlist(atest$values) - unlist(s$loga.equil), all.equal, 0))) +}) Modified: pkg/CHNOSZ/vignettes/anintro.Rmd =================================================================== --- pkg/CHNOSZ/vignettes/anintro.Rmd 2018-10-31 03:29:20 UTC (rev 336) +++ pkg/CHNOSZ/vignettes/anintro.Rmd 2018-10-31 06:25:35 UTC (rev 337) @@ -895,13 +895,13 @@ a25 <- affinity(pH = c(4, 13)) a150 <- affinity(pH = c(4, 13), T = 150) diagram(a25, dy = 0.4) -diagram(a150, add = TRUE, col = "red") +diagram(a150, add = TRUE, names = NULL, col = "red") e25 <- equilibrate(a25, loga.balance = -3) e150 <- equilibrate(a150, loga.balance = -3) diagram(e25, ylim = c(-6, 0), dy = 0.15) -diagram(e150, add = TRUE, col = "red") +diagram(e150, add = TRUE, names = NULL, col = "red") diagram(e25, alpha = TRUE, dy = -0.25) -diagram(e150, alpha = TRUE, add = TRUE, col = "red") +diagram(e150, alpha = TRUE, add = TRUE, names = NULL, col = "red") ``` The distribution of aqueous carbonate species as a function of pH (a type of Bjerrum plot) is a classic example of an equilibrium calculation.