# definition of a function to calculate the modified z score.
def modified_z_score(intensity):
median_int = np.median(intensity)
mad_int = np.median([np.abs(intensity - median_int)])
modified_z_scores = 0.6745 * (intensity - median_int) / mad_int
return modified_z_scores
# Once the spike detection works, the spectrum can be fixed by calculating the average of the previous and the next point to the spike. y is the intensity values of a spectrum, m is the window which we will use to calculate the mean.
def fixer(y,m):
threshold = 7 # binarization threshold.
spikes = abs(np.array(modified_z_score(np.diff(y)))) > threshold
y_out = y.copy() # So we don't overwrite y
for i in np.arange(len(spikes)):
if spikes[i] != 0: # If we have an spike in position i
w = np.arange(i-m,i+1+m) # we select 2 m + 1 points around our spike
w2 = w[spikes[w] == 0] # From such interval, we choose the ones which are not spikes
y_out[i] = np.mean(y[w2]) # and we average the value
return y_out
2条答案
按热度按时间0pizxfdo1#
一个简单的解决方案可能是使用Whitaker和Hayes提出的算法,他们在频谱导数上使用修改后的z得分,这篇中等大小的帖子解释了它是如何工作的,以及它在python https://towardsdatascience.com/removing-spikes-from-raman-spectra-8a9fdda0ac22中的实现。
其思想是计算光谱导数的修正z值,并应用阈值来检测宇宙尖峰,然后应用固定器来移除尖峰点,并将其替换为周围像素的平均值。
fjnneemd2#
答案取决于数据的外观:如果你能读取二维CCD的读数,并从中产生一维光谱,那么你可以使用lacosmic模块来去除那里的宇宙射线。如果你只有一维光谱,但有来自同一来源的多个光谱,然后是一个简短的广告一个特别的解决方案是对光谱进行粗略的归一化,并去除比其他光谱中的对应像素亮几倍的那些像素如果每个源只有一个一维光谱,那么一个不太可靠的选择是移除所有比相邻像素亮得多的像素。(根据宇宙的形状,你甚至可能想移除最近的5个像素或其他像素,以捕捉宇宙射线峰的翅膀)。