Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplification of the inital and boundary values interface for fitsignal #71

Merged
merged 5 commits into from
Jan 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 17 additions & 20 deletions deerlab/fitsignal.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import numpy as np
import types
import copy
import inspect
import matplotlib.pyplot as plt
import deerlab as dl
from deerlab.classes import UncertQuant, FitResult
Expand All @@ -15,7 +14,8 @@
from deerlab.utils import isempty, goodness_of_fit, Jacobian

def fitsignal(Vexp, t, r, dd_model='P', bg_model=bg_hom3d, ex_model=ex_4pdeer,
par0=[None,None,None], lb=[None,None,None], ub=[None,None,None], verbose= False,
dd_par0=None, bg_par0=None, ex_par0=None, verbose= False,
dd_lb=None, bg_lb=None, ex_lb=None, dd_ub=None, bg_ub=None, ex_ub=None,
weights=1, uqanalysis=True, regparam='aic', regtype = 'tikhonov'):
r"""
Fits a dipolar model to the experimental signal ``V`` with time axis ``t``, using
Expand Down Expand Up @@ -66,23 +66,20 @@ def fitsignal(Vexp, t, r, dd_model='P', bg_model=bg_hom3d, ex_model=ex_4pdeer,

The default is ``ex_4pdeer``.

par0 : list of array_like, optional
Starting parameter values. Must be a 3-element list ``[par0_dd,par0_bg,par0_ex]``
containing the start values of the distribution, background and experiment models, in that order.
If a model does not require parameters or are to be determined automatically it must be specified
as an empty list ``[]``. The default is ``par0=[[],[],[]]``.
dd_par0, bg_par0, ex_par0 : array_like, optional
Initial parameter values of the distance distribution/background/experimental model parameters.
If a model does not require parameters or are to be determined automatically it can be omitted or specified
as ``None`` (default).

lb : list of array_like, optional
Lower bounds for parameters. Must be a 3-element list ``[lb_dd,lb_bg,lb_ex]``
containing the start values of the distribution, background and experiment models, in that order.
If a model does not require parameters or are to be determined automatically it must be specified
as an empty list ``[]``. The default is ``lb=[[],[],[]]``.
dd_lb, bg_lb, ex_lb : array_like, optional
Lower boundary values of the distance distribution/background/experimental model parameters.
If a model does not require parameters or are to be determined automatically it can be omitted or specified
as ``None`` (default).

ub : list of array_like, optional
Upper bounds for parameters, Must be a 3-element list ``[ub_dd,ub_bg,ub_ex]``
containing the start values of the distribution, background and experiment models, in that order.
If a model does not require parameters or are to be determined automatically it must be specified
as an empty list ``[]``. The default is ``ub=[[],[],[]]``.
dd_ub, bg_ub, ex_ub : array_like, optional
Upper boundary values of the distance distribution/background/experimental model parameters.
If a model does not require parameters or are to be determined automatically it can be omitted or specified
as ``None`` (default).

weights : array_like, optional
Array of weighting coefficients for the individual signals in global fitting,
Expand Down Expand Up @@ -231,9 +228,9 @@ def fitsignal(Vexp, t, r, dd_model='P', bg_model=bg_hom3d, ex_model=ex_4pdeer,
if len(ex_model)!=nSignals:
ex_model = ex_model*nSignals

par0 = [[] if par0_i is None else par0_i for par0_i in par0]
lb = [[] if lb_i is None else lb_i for lb_i in lb]
ub = [[] if ub_i is None else ub_i for ub_i in ub]
par0 = [[] if par0_i is None else par0_i for par0_i in [dd_par0,bg_par0,ex_par0]]
lb = [[] if lb_i is None else lb_i for lb_i in [dd_lb,bg_lb,ex_lb]]
ub = [[] if ub_i is None else ub_i for ub_i in [dd_ub,bg_ub,ex_ub]]
if type(par0) is not list or len(par0)!=3:
raise TypeError('Initial parameters (7th input) must be a 3-element cell array.')

Expand Down
1 change: 1 addition & 0 deletions examples/plot_extracting_gauss_constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
# %%
fit = dl.fitsignal(V,t,r,'P',dl.bg_exp,dl.ex_4pdeer)
fit.plot()
plt.show()

# %% [markdown]
# Fit Gaussians to the distance distribution
Expand Down
14 changes: 3 additions & 11 deletions examples/plot_fitting_5pdeer.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,16 @@
# pathway amplitudes pretty much unconstrained.
#

# %% [markdown]
# Define initial values and bounds for model parameters
# %%
ex_lb = [ 0, 0, 0, max(t)/2-1] # lower bounds
ex_ub = [100, 100, 100, max(t)/2+1] # upper bounds
luisfabib marked this conversation as resolved.
Show resolved Hide resolved
ex_par0 = [0.5, 0.5, 0.5, max(t)/2 ] # start values

# %% [markdown]
# In this case we only want to set the bounds for the experiment
# parameters, so we can leave the rest empty:
#

# %%
ub = [[],[],ex_ub]
lb = [[],[],ex_lb]
par0 = [[],[],ex_par0]

# %% [markdown]
# Run the fit with a 5-pulse DEER signal model

# %%
fit = dl.fitsignal(Vexp,t,r,'P',dl.bg_hom3d,dl.ex_5pdeer,par0,lb,ub)
fit = dl.fitsignal(Vexp,t,r,'P',dl.bg_hom3d,dl.ex_5pdeer,par0_ex=ex_par0,lb_ex=ex_lb,ub_ex=ex_ub)
fit.plot()
2 changes: 1 addition & 1 deletion examples/plot_fitting_mixed_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
#
# Let's say our intuiton (which, since we know the ground truth, is exact) on
# the sample indicates that our distribution is a llinear combination of a Gaussian
# distirbution and a worm-like chain model. While DeerAnalysis provides built-in
# distribution and a worm-like chain model. While DeerLab provides built-in
# parametric models for both models, we require a combination of both.
#
# For such cases we can use the ``mixmodels`` function to create a custom mixed
Expand Down
1 change: 1 addition & 0 deletions examples/plot_param_uncertainty_propagation.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
plt.grid(alpha=0.3)
plt.legend(['truth','Pfit','Pfit 95%-CI'])

plt.show()

# %%

Expand Down
1 change: 0 additions & 1 deletion examples/plot_pseudotitration_parameter_free.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,5 @@ def Kmodel(par,ts,rA,rB,L):
plt.legend(['state A','state B'])
plt.ylim([0,1])

plt.tight_layout()
plt.show()
# %%
11 changes: 4 additions & 7 deletions test/test_fitsignal.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,7 @@ def test_start_values():
K = dipolarkernel(t,r,lam,Bmodel)
V = K@P

par0 = [[],0.5,0.5]
fit = fitsignal(V,t,r,'P',bg_exp,ex_4pdeer,par0,uqanalysis=False)
fit = fitsignal(V,t,r,'P',bg_exp,ex_4pdeer,bg_par0=0.5,ex_par0=0.5,uqanalysis=False)

assert ovl(P,fit.P) > 0.95
# ======================================================================
Expand All @@ -145,15 +144,13 @@ def test_boundaries():
K = dipolarkernel(t,r,lam,Bmodel)
V = K@P

par0 = [[],0.4,0.4]
lb = [[],0.2,0.2]
ub = [[],0.5,0.5]
fit = fitsignal(V,t,r,'P',bg_exp,ex_4pdeer,par0,lb,ub,uqanalysis=False)
fit = fitsignal(V,t,r,'P',bg_exp,ex_4pdeer, uqanalysis=False,
bg_par0=0.4, bg_lb=0.2, bg_ub=0.5,
ex_par0=0.4, ex_lb=0.2, ex_ub=0.5)

assert ovl(P,fit.P) > 0.95
# ======================================================================


def test_global_4pdeer():
# ======================================================================
"Check the correct fit of two 4-DEER signals"
Expand Down