You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用models.Gaussian1D拟合吸收谱线,结果呈线性而非高斯分布

问题分析与修正方案

你的拟合结果变成线性分布,核心原因是吸收谱线的特征与你设置的高斯模型初始参数不匹配,且未考虑连续谱背景的影响,具体问题和解决办法如下:

1. 吸收谱线的振幅初始值错误

吸收谱线是通量低于连续谱的“谷”,但你用np.max(fluxNE)作为高斯振幅的初始值,这会让模型一开始就朝着“峰”的方向拟合,和实际吸收特征完全相反。

修正:

  • 先估算连续谱基线(比如取裁剪区间两端的通量平均值)
  • 振幅初始值设为**(通量最小值 - 基线)**,也就是负数,对应吸收谷的深度

2. 缺少连续谱背景模型

真实光谱的吸收线是叠加在连续谱(可能是线性或常数)之上的,单纯用高斯模型拟合会让算法被迫用高斯参数去拟合背景,最终得到近似线性的结果。

修正:

  • 用Gaussian1D + Linear1D组合模型,同时拟合吸收线和背景

3. 初始参数优化

确保高斯的中心波长、宽度初始值贴近真实谱线:

  • 中心波长可以用吸收谷对应的实际波长(而非直接用文件里的理论值,避免谱线偏移影响)
  • 确认文件中lineWidth的定义:如果是标准差(sigma),则直接使用;如果是半高全宽(FWHM),需要转换为sigma = lineWidth / 2.3548

修正后的代码

import os
import numpy as np
import matplotlib.pyplot as plt
from astropy.modeling import models, fitting

data_folder_path = '/home/marzie/Documents/new measurement section/measurement/test' #data address
molecules_wave_list = '/home/marzie/Documents/new measurement section/measurement/Table of DIBS (copy).txt' #source molecules (Hobbs data)

data_files = [file for file in os.listdir(data_folder_path) if file.endswith('.txt')]

for file in data_files: 
    #Reading data
    file_path = os.path.join(data_folder_path, file)
    wave, flux = np.loadtxt(file_path, unpack=True)
    file_name = os.path.splitext(file)[0]    # Extract file name without extension

    #Cut the spectrum for desired molecule
    with open(molecules_wave_list, 'r') as molec:  
        next(molec) # skip header
        for line in molec:       
            molec_value = line.split() 
            central_wave_file = float(molec_value[0]) 
            sigma_file = float(molec_value[1]) # 假设文件里的是标准差(sigma)
            fwhm = 2.3548 * sigma_file
            # 裁剪范围:用FWHM的3倍左右,避免包含过多无关背景
            cut_range = max(3*fwhm, 2.0)
            idx = (wave >= central_wave_file - cut_range) & (wave <= central_wave_file + cut_range)
            waveNE = wave[idx]
            fluxNE = flux[idx]

            # 1. 估计连续谱基线(取区间两端的平均值)
            baseline = np.mean([fluxNE[:10].mean(), fluxNE[-10:].mean()])
            # 2. 找到吸收谷的位置和深度,作为高斯初始参数
            min_flux_idx = np.argmin(fluxNE)
            peak_wave = waveNE[min_flux_idx]
            peak_amp = fluxNE[min_flux_idx] - baseline # 负数值,对应吸收谷

            # 3. 组合模型:高斯(吸收)+ 线性背景
            gauss = models.Gaussian1D(amplitude=peak_amp, mean=peak_wave, stddev=sigma_file)
            linear = models.Linear1D(slope=0, intercept=baseline)
            combined_model = gauss + linear

            # 4. 拟合模型
            fit_g = fitting.LevMarLSQFitter()
            fitted_model = fit_g(combined_model, waveNE, fluxNE)            

            # 绘图
            plt.figure(figsize=(8,5))
            plt.plot(waveNE, fluxNE, label='观测数据')
            plt.plot(waveNE, fitted_model(waveNE), label='拟合结果', linewidth=2)
            plt.title(f'{file_name} - 吸收线高斯拟合')
            plt.xlabel('波长')
            plt.ylabel('通量')
            plt.legend()
            plt.show()

额外注意事项

  • 如果文件里的lineWidth是半高全宽(FWHM),需将sigma_file改为float(molec_value[1]) / 2.3548
  • 若裁剪后的连续谱是水平的,可替换Linear1D为Constant1D作为背景模型
  • 拟合前先检查裁剪后的waveNE和fluxNE是否包含清晰的吸收谷,避免裁剪范围错误导致无有效谱线

内容的提问来源于stack exchange,提问作者marzieh Faraji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 23:43:44