使用两个高斯的 lmfit 如何根据第一个峰来限制第二个峰的参数?
Using lmfit of two Gaussians how to restrain the parameters of the second peak in dependence of the first?
在多峰拟合中,我打算根据第一个峰的值来约束第二个峰参数的解space。特别是我想让第二个的振幅参数永远不会大于第一个的振幅。
我在 lmfit 网站上读到过关于 "Using Inequality Constraints" 的信息,我觉得这种方法应该可行,但我不太了解它,无法让它发挥作用。
import lmfit
GaussianA = lmfit.models.GaussianModel(prefix='A_')
pars = GaussianA.make_params()
GaussianB = lmfit.models.GaussianModel(prefix='B_')
pars.update(GaussianB.make_params())
pars['B_amplitude'].set(expr = 'A_amplitude')
这会将 B 的振幅锁定为 A 的振幅。
但是,如何指定B的振幅最多为'A_amplitude'
?
这行不通(但如果真的那么简单那就太棒了)但也许有助于展示我想要的东西):pars['B_amplitude'].set(1,max='A_amplitude')
你有你的数据图吗,它有多嘈杂?我了解到您进行了 2 次单独的拟合,但您的数据中有 2 个峰值。如果您的数据是友好的,您可以拟合第一个峰值,然后获取它的振幅并通过设置 limits 的振幅来拟合第二个峰值。但也许最好为 x 位置设置一个限制,因为您正在谈论两个不同的峰值。
我是如何以一种有点老套的方式解决这个问题的(我假设你的问题是你的拟合不收敛):
- 在数据中找到最高峰(最大值)-> x1
- 截取峰环境中的数据(x1 +- 2 半功率宽度,取决于峰的距离和峰的高度)
- 在新的约简数据中找到最高峰(最大值)-> x2
使用自定义拟合曲线,它是两条高斯曲线的总和。 f(x) = gauss1 + gauss2
,其中 gauss(x, x1, width, amplitude, y_offset)
和 gauss = amplitude/width * e^(-(x-x1)^2/width) + y_offset
抱歉,我是几年前做的,没有 lmfit,所以我不能给你详细信息。
lmfit.Parameter
的 min
和 max
值不是根据其他变量动态计算的,但必须是真实数值。也就是说,类似于
pars['B_amplitude'].set(1,max='A_amplitude') # Nope!
不会工作。
您需要做的是遵循不等式约束的文档(请参阅 https://lmfit.github.io/lmfit-py/constraints.html#using-inequality-constraints)。即你可以想到
B_amplitude < A_amplitude
作为
B_amplitude = A_amplitude - delta_amplitude
其中 delta_amplitude
是一些必须为正的变量值。
可以表示为
GaussianA = lmfit.models.GaussianModel(prefix='A_')
pars = GaussianA.make_params()
GaussianB = lmfit.models.GaussianModel(prefix='B_')
pars.update(GaussianB.make_params())
pars.add('delta_amplitude', value=0.01, min=0, vary=True)
pars['B_amplitude'].set(expr = 'A_amplitude - delta_amplitude')
现在delta_amplitude
是一个必须为正的变量,而B_amplitude
不再是一个自由变化的参数,而是受到A_amplitude
和delta_amplitude
值的约束.
在多峰拟合中,我打算根据第一个峰的值来约束第二个峰参数的解space。特别是我想让第二个的振幅参数永远不会大于第一个的振幅。
我在 lmfit 网站上读到过关于 "Using Inequality Constraints" 的信息,我觉得这种方法应该可行,但我不太了解它,无法让它发挥作用。
import lmfit
GaussianA = lmfit.models.GaussianModel(prefix='A_')
pars = GaussianA.make_params()
GaussianB = lmfit.models.GaussianModel(prefix='B_')
pars.update(GaussianB.make_params())
pars['B_amplitude'].set(expr = 'A_amplitude')
这会将 B 的振幅锁定为 A 的振幅。
但是,如何指定B的振幅最多为'A_amplitude'
?
这行不通(但如果真的那么简单那就太棒了)但也许有助于展示我想要的东西):pars['B_amplitude'].set(1,max='A_amplitude')
你有你的数据图吗,它有多嘈杂?我了解到您进行了 2 次单独的拟合,但您的数据中有 2 个峰值。如果您的数据是友好的,您可以拟合第一个峰值,然后获取它的振幅并通过设置 limits 的振幅来拟合第二个峰值。但也许最好为 x 位置设置一个限制,因为您正在谈论两个不同的峰值。
我是如何以一种有点老套的方式解决这个问题的(我假设你的问题是你的拟合不收敛):
- 在数据中找到最高峰(最大值)-> x1
- 截取峰环境中的数据(x1 +- 2 半功率宽度,取决于峰的距离和峰的高度)
- 在新的约简数据中找到最高峰(最大值)-> x2
使用自定义拟合曲线,它是两条高斯曲线的总和。 f(x) = gauss1 + gauss2
,其中 gauss(x, x1, width, amplitude, y_offset)
和 gauss = amplitude/width * e^(-(x-x1)^2/width) + y_offset
抱歉,我是几年前做的,没有 lmfit,所以我不能给你详细信息。
lmfit.Parameter
的 min
和 max
值不是根据其他变量动态计算的,但必须是真实数值。也就是说,类似于
pars['B_amplitude'].set(1,max='A_amplitude') # Nope!
不会工作。
您需要做的是遵循不等式约束的文档(请参阅 https://lmfit.github.io/lmfit-py/constraints.html#using-inequality-constraints)。即你可以想到
B_amplitude < A_amplitude
作为
B_amplitude = A_amplitude - delta_amplitude
其中 delta_amplitude
是一些必须为正的变量值。
可以表示为
GaussianA = lmfit.models.GaussianModel(prefix='A_')
pars = GaussianA.make_params()
GaussianB = lmfit.models.GaussianModel(prefix='B_')
pars.update(GaussianB.make_params())
pars.add('delta_amplitude', value=0.01, min=0, vary=True)
pars['B_amplitude'].set(expr = 'A_amplitude - delta_amplitude')
现在delta_amplitude
是一个必须为正的变量,而B_amplitude
不再是一个自由变化的参数,而是受到A_amplitude
和delta_amplitude
值的约束.