Skip to content
Prev 170780 / 398525 Next

Chromatogram deconvolution and peak matching

Hoi Bart,

I think you're right that ALS should be applicable to this problem.
Unfortunately in writing I see that there is a bug when the spectra are
NOT constrained to nonnegative values (the package has been used to my
knowledge only in fitting multiway mass spectra thus far, where this
constraint is always applied); I'll have a patched version soon.

I'd be interested in hearing about where the manual could be improved,
too.

#2D chromatogram generation

time <- seq(0,20,by=0.05)
f <- function(x,rt) dnorm((x-rt),mean=0,sd=rt/35)
C1 <- matrix(c( f(time,6.1), f(time,5.6), f(time,15)), nrow=401,ncol=3)
C2 <- matrix(c( f(time,2.1), f(time,4), f(time,8)), nrow=401,ncol=3)

#spectrum generation
spectra <- function(x,a,b,c,d,e) a + b*(x-e) + c*((x-e)^2) + d*((x-e)^3)
x <- 220:300
s1 <- spectra(x,(-194.2),2.386,(-0.009617),(1.275e-05),0)
s2 <- spectra(x,(-1.054e02),1.3,(-5.239e-03),(6.927e-06),-20)
s3 <- spectra(x,(-194.2),2.386,(-0.009617),(1.275e-05),20)
spec <- matrix(c(s1,s2,s3), nrow=81,ncol=3)

## data matrix 1
chrom1 <- C1 %*% t(spec)

## data matrix 2
chrom2 <- C2 %*% t(spec)

require(ALS)

## you want to recover 2 (401 x 3) matrices C1 and C2 and a
## (82 x 3) matrix E such that
## chrom1 = C1 E^T, chrom2 = C2 E^T

## some starting guess for elution profiles
## these need to be pretty good
Cstart1 <- matrix(c( f(time,4), f(time,6), f(time,12)), nrow=401,ncol=3)
Cstart2 <- matrix(c( f(time,3), f(time,5), f(time,10)), nrow=401,ncol=3)

xx <- als( CList = list(Cstart1, Cstart2), PsiList = list(chrom1, chrom2),
          S=matrix(1, nrow=81, ncol=3), x=time, x2=x, uniC=TRUE,
          normS=TRUE, nonnegS=TRUE)

par(mfrow=c(3,1))

matplot(time, xx$CList[[1]], col=2, type="l",
        main="elution profiles chrom1", lty=1,
        ylab="amplitude")

matplot(time, C1, col=1, add=TRUE, type="l", lty=1)

legend(10,2,legend=c("real", "estimated"), col=1:2, lty=1)

matplot(time, xx$CList[[2]], col=2, type="l",
        main="elution profiles chrom2", lty=1,
        ylab="amplitude")

matplot(time, C2, col=1, add=TRUE, type="l", lty=1)

legend(10,6,legend=c("real", "estimated"), col=1:2, lty=1)

matplot(x, xx$S, col=2, type="l", main="spectra", lty=1,
        ylab="amplitude")

matplot(x, spec, col=1, add=TRUE, type="l", lty=1)

legend(270,.95,legend=c("real", "estimated"), col=1:2, lty=1)
On Tue, 17 Feb 2009, bartjoosen wrote: