信号和错误分析的背景减法

机器算法验证 协方差 协方差矩阵 错误传播
2022-03-20 17:22:35

我使用 CCD 来查看由于塞曼效应导致的能级分裂。

我有一个 7926 像素的一维 CCD,每个 7μm。我的 CCD 分析了一个二维区域,然后它前进了 200 次。所以,我有一个这样的矩阵“矩阵”

我选择 40 到 60 像素之间的背景,并为每一行计算平均值。然后,我将这 7926 个平均值投影到 Y 轴上。因此,对于矩阵行的每个 bin(即 3040),我减去背景的 3040 像素的内容的值

这是我的背景:“背景”

(在 x 中有我的 CCD 的像素,y 是强度)。

我必须从信号中减去背景,为 bin 减去 bin。在背景的每个 bin 中,它关联一个错误,其中是 bin 内容。σ=NN

信号的每个箱都有一个误差,但是当我减去背景时,我如何计算纯信号的确切误差?如果是减法后的 bin 内容,是之前的 bin 内容,是背景的 bin 内容,则和误差(抛出传播)NZiZiYiZi=ZiYiσYi=σZi2+σYi2+....

事实上,我认为,应该有一个协方差项。我该如何计算它?

2个回答

正确估计该错误将是棘手的。但我想建议首先找到一个更好的程序来减去背景更重要。只有当一个好的程序可用时,才值得分析错误的数量。

在这种情况下,使用平均值会因信号的贡献而向上偏移,这看起来足够重要。而是使用更强大的估计器。一个简单的就是中位数。 此外,通过同时调整列和行,可以从这些数据中挤出更多。这称为“中值抛光”。它执行速度非常快,并且在某些软件中可用(例如R)。

这些 793 行 200 列的模拟数据图显示了使用中值抛光调整背景的结果。(忽略 y 轴上的标签;它们是用于显示数据的软件的产物。)

图1

调整后的数据中仍然存在非常轻微的偏差:顶部和底部的四分之一,其中信号不存在于任何列中,比中间的一半略绿。然而,相比之下,仅从数据中减去行均值会产生明显的偏差:

图 2

实际背景与估计背景的散点图(此处未显示,但由代码生成)证实了中值抛光的优越性。

现在,这有点不公平,因为要计算背景,您之前选择了被认为没有信号的列。但是这样做存在问题:

  • 如果这些区域中存在低电平信号(您没有看到或预期),它们会使结果产生偏差。

  • 只使用了一小部分数据,放大了背景中的估计误差。(与使用看起来很少或没有信号的十分之九的色谱柱相比,仅使用十分之一的可用色谱柱估计背景的误差大约是三倍。)

此外,即使您确信某些列不包含信号,您仍然可以对这些列应用中值抛光。这将保护您免受意外违反您的期望(这些是无信号区域)。此外,这种稳健性将允许您扩大用于估计背景的列的集合,因为如果您无意中包含了一些带有某些信号的列,它们只会产生微不足道的影响。

也许本着我对最近一个相关问题的回答的精神,可以进行额外的处理以识别孤立的异常值并估计和提取信号。


R代码:

#
# Create background.
#
set.seed(17)
i <- 1:793
row.sd <- 0.08
row.mean <- log(60) - row.sd^2/2
background <- exp(rnorm(length(i), row.mean, row.sd))
k <- sample.int(length(background), 6)
background[k] <- background[k] * 1.7

par(mfrow=c(1,1))
plot(background, type="l", col="#000080")
#
# Create a signal.
#
j <- 1:200
f <- function(i, j, center, amp=1, hwidth=5, l=0, u=6000) {
  0.2*amp*outer(dbeta((i-l)/(u-l), 3, 1.1), pmax(0, 1-((j-center)/hwidth)^4))
}
#curve(f(x, 10, center=10), 0, 6000)
#image(t(f(i,j, center=100,u=600)), col=c("White", rainbow(100)))

u <- 600
signal <- f(i,j, center=10, amp=110, u=u) +
  f(i,j, center=90, amp=90, u=u) +
  f(i,j, center=130, amp=80, u=u)
#
# Combine signal and background, both with some iid multiplicative error.
#
ccd <- outer(background, j, function(i,j) i) * exp(rnorm(length(signal), sd=0.05)) + 
  signal * exp(rnorm(length(signal), sd=0.1))
ccd <- matrix(pmin(120, ccd), nrow=length(i))
#image(j, i, t(ccd), col=c(rep("#f8f8f8",20), rainbow(100)),main="CCD")
#
# Compute background via row means (not recommended).
# (Returns $row and $overall to match the values of `medpolish`.)
#
mean.subtract <- function(x) {
  row <- apply(x, 1, mean)
  overall <- mean(row)
  row <- row - overall
  return(list(row=row, overall=overall))
}
#
# Estimate background and adjust the image.
#
fit <- medpolish(ccd)
#fit <- mean.subtract(ccd)
ccd.adj <- ccd - outer(fit$row, j, function(i,j) i)
image(j, i, t(ccd.adj), col=c(rep("#f8f8f8",20), rainbow(100)), 
      main="Background Subtracted")
plot(fit$row + fit$overall, type="l", xlab="i")
plot(background, fit$row)
#
# Plot the results.
#
require(raster)
show <- function(y, nrows, ncols, hillshade=TRUE, aspect=1, ...) {
  x <- apply(y, 2, rev)
  x <- raster(x, xmn=0, xmx=ncols, ymn=0, ymx=nrows*aspect)
  crs(x) <- "+proj=lcc +ellps=WGS84"
  if (hillshade) {
    slope <- terrain(x, opt='slope')
    aspect <- terrain(x, opt='aspect')
    hill <- hillShade(slope, aspect, 10, 60)
    plot(hill, col=grey(0:100/100), legend=FALSE, ...)
    alpha <- 0.5; add <- TRUE
  } else {
    alpha <- 1; add <- FALSE
  }
  plot(x, col=rainbow(127, alpha=alpha), add=add, ...)
}

par(mfrow=c(1,2))
asp <- length(j)/length(i) * 6/8
show(ccd, length(i), length(j), aspect=asp, main="Raw Data")
show(ccd.adj, length(i), length(j), aspect=asp, main="Adjusted Data")

关于背景计算:由于您正在做的是通过计算仅具有背景的某些值的平均值来测量背景,因此您可以使用平均值的误差(σBckg/navg) 并且这应该正确估计背景变化,同时考虑到背景之间的变化navg您考虑的像素。

您还可以计算Zi错误,如果我理解正确的话,它是由N,所以这就解决了。为了计算误差之间的协方差,您可以使用协方差公式(并在此处查看有关两个变量之间协方差的示例)。我不是最了解它的人,所以我希望这种漫无边际的讨论能吸引更多受过教育的人来讨论。=)