diff --git a/.github/ISSUE_TEMPLATE/---bug-report.md b/.github/ISSUE_TEMPLATE/---bug-report.md
new file mode 100644
index 000000000..f4f998475
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/---bug-report.md
@@ -0,0 +1,34 @@
+---
+name: "\U0001F41B Bug report"
+about: Something is no working and needs a fix.
+title: "[BUG] A short description of the bug"
+labels: bug
+assignees: ''
+
+---
+
+### Describe the bug
+A clear and concise description of what the bug is.
+
+### Environment
+**DeerLab Version:** X.X.X
+**Python Version:** X.X.X
+**OS:** Windows, Max, Linux?
+
+### How to reproduce it?
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+### Expected behavior
+A clear and concise description of what you expected to happen.
+
+### Code Snippet
+````
+Copy-paste your code here
+````
+
+### Files
+If there are any files required to run your code please upload them.
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index aee5fbd3f..2ab868158 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -3,6 +3,9 @@ on:
schedule:
# Run every 2rd day at 6:30 AM
- cron: '30 6 * * 1/2'
+ pull_request:
+ branches:
+ - master
jobs:
build:
diff --git a/.github/workflows/deploy_ghpages.yml b/.github/workflows/deploy_ghpages.yml
new file mode 100644
index 000000000..57cfa2bea
--- /dev/null
+++ b/.github/workflows/deploy_ghpages.yml
@@ -0,0 +1,51 @@
+name: Docs Build & Deployment
+
+on:
+ push:
+ branches:
+ - manual_ghp_update
+ - master
+ paths:
+ - 'docsrc/**'
+ schedule:
+ # Run once a week on Sunday at 12:00 PM
+ - cron: '0 12 * * 0'
+
+jobs:
+
+ deploy:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v1
+ - name: Set up Python 3.7
+ uses: actions/setup-python@v1
+ with:
+ python-version: 3.7
+ - uses: actions/cache@v2
+ with:
+ path: |
+ ~/.cache/pip
+ key: ${{ runner.os }}-${{ hashFiles('**/make.bat') }}
+ restore-keys: |
+ {{ runner.os }}-pip-
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ python -m pip install sphinx==1.8.0
+ python -m pip install sphinx_rtd_theme
+ python -m pip install numpydoc
+ python -m pip install sphinx-gallery
+ python -m pip install sphinxcontrib-httpdomain
+ sudo apt install texlive-extra-utils
+ sudo apt-get install texlive-latex-extra
+ python -m pip install .
+ - name: Build with Sphinx
+ run: |
+ sphinx-build -E -b html ./docsrc/source ./docs
+
+ - name: Deploy to GH-Pages
+ uses: peaceiris/actions-gh-pages@v3
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: ./docs
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 241afbb97..2ae6d0ffb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,3 +23,5 @@ docsrc/__pycache__/
dist/
build/
.debugging.py
+multidocs/**/*
+docsrc/source/auto_examples/**/*
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 000000000..d65727874
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,36 @@
+
+-------------------------------
+
+Version 0.10.0 - August 2020
+-----------------------------
+
+As of this version, DeerLab is written in Python in contrast to older versions based on MATLAB.
+
+Deprecated functions
+ The following functions have been deprecated due to limited usability or due to functionality overlap with other DeerLab functions: ``aptkernel``, ``backgroundstart``, ``fitbackground``, ``paramodel``, and ``time2freq``.
+
+Overall changes
+ * All fit functions now return a single ``FitResult`` output which will contain all results.
+
+ * All functions are now compatible with non-uniformly increasing distance axes.
+
+ * All fit functions are completely agnostic with respect of the abolute values of the signal amplitude. This is automatically fitted by all function and return as part of the results.
+
+ * Uncertainty quantification for all fit functions is returned as a ``UncertQuant`` object from which confidence intervals, parameter distributions, etc. can be generated generalizing the uncertainty interface for all DeerLab. Uncertainty can now be propagated to arbitrary functions.
+
+Specific changes
+ * ``fitparamodel``: the functionality has been streamlined. Function now fits arbitrary parametric models using non-linear leas-squares without consideration of whether it is a time-domain or distance-domain model. The models no longer need to take two inputs (axis+parameters) and now only tk the parameters as input.
+
+ * ``fitregmodel``: goodness-of-fit estimators are now computed using the proper estimation the degrees of freedom.
+
+ * ``fitmultimodel``: added internal measures to avoid situations where one or several components are suppressed by fitting zero-amplitudes making the method more stable.
+
+ * ``uqst``: the uncertainty distributions of the parameters are now returned as properly normalized probability density functions.
+
+ * ``fftspec``: frequency axis construction has been corrected.
+
+ * ``regoperator``: now calculates the numerically exact finite-difference matrix using Fornberg's method.
+
+ * ``correctphase``: now can handle 2D-datasets.
+
+-------------------------------
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index aa489e720..3d7ed3f71 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2019 Luis Fabregas, Stefan Stoll, Gunnar Jeschke
+Copyright (c) 2019-2020 Luis Fabregas, Stefan Stoll, Gunnar Jeschke
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 000000000..b1fc69e0a
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1 @@
+include VERSION
\ No newline at end of file
diff --git a/README.md b/README.md
index 04f25e3c3..50324f2da 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,45 @@
-# PyDeerLab
+
+
+
+
-This is a Python port of the DeerLab MATLAB toolbox.
+### About
+DeerLab is a Python package for the analysis of dipolar EPR (electron paramagnetic resonance) spectroscopy data. Dipolar EPR spectroscopy techniques include DEER (double electron-electron resonance), RIDME (relaxation-induced dipolar modulation enhancement), and others. The documentation can be found [here](https://jeschkelab.github.io/DeerLab/index.html).
+
+DeerLab consists of a collection of functions for modelling, data processing, and least-squares fitting. They can be combined in scripts to build custom data analysis workflows. DeerLab supports both classes of distance distribution models: non-parametric (Tikhonov regularization and related) and parametric (multi-Gaussians etc). It also provides a selection of background and experiment models.
+
+The early versions of DeerLab (up to version 0.9) are written in MATLAB. The old MATLAB codebase is archived and can be found [here](https://github.com/JeschkeLab/DeerLab-Matlab).
+
+### Requirements
+
+DeerLab is available for Windows, Mac and Linux systems and requires **Python 3.6**, **3.7**, or **3.8**.
+
+All additional dependencies are automatically downloaded and installed during the setup.
+
+### Setup
+
+A pre-built distribution can be installed using `pip`.
+
+First, ensure that `pip` is up-to-date. From a terminal (preferably with administrative privileges) use the following command:
+
+ python -m pip install --upgrade pip
+
+Next, install DeerLab with
+
+ python -m pip install deerlab
+
+More details on the installation of DeerLab can be found [here](https://jeschkelab.github.io/DeerLab/installation.html).
+
+### Citation
+
+A paper about DeerLab is currently submitted for publication. When you use DeerLab in your work, for now, please cite the preprint
+
+> Fábregas Ibáñez, L., Jeschke, G., and Stoll, S.: DeerLab: A comprehensive software package for analyzing dipolar EPR spectroscopy data, Magn. Reson. Discuss., https://doi.org/10.5194/mr-2020-13, 2020
+
+Please check back frequently for updated publication information.
+
+### License
+
+The DeerLab toolbox is licensed under the [MIT License](LICENSE).
+
+Copyright (c) 2019-2020: Luis Fábregas Ibáñez, Stefan Stoll, Gunnar Jeschke, and [other contributors](https://github.com/JeschkeLab/DeerLab/contributors).
diff --git a/VERSION b/VERSION
index 29b2d3ea5..f78dc3652 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.10.0-dev
+v0.10.0
\ No newline at end of file
diff --git a/deerlab/bootan.py b/deerlab/bootan.py
index a2c5809e0..9bb2b29f6 100644
--- a/deerlab/bootan.py
+++ b/deerlab/bootan.py
@@ -102,7 +102,7 @@ def myfcn(V):
# Inform of progress if requested
if verbose:
- print('\r Bootstrapping: #{}/#{} samples finished'.format(iSample,nSamples))
+ print('Bootstrapping: #{}/#{} samples finished'.format(iSample+1,nSamples), end='\r', flush=True)
for i in range(nSignals):
diff --git a/deerlab/classes.py b/deerlab/classes.py
index 2221ad84a..87509f1f5 100644
--- a/deerlab/classes.py
+++ b/deerlab/classes.py
@@ -79,7 +79,7 @@ def __dir__(self):
# Copyright(c) 2019-2020: Luis Fabregas, Stefan Stoll and other contributors.
import numpy as np
-from deerlab.utils import jacobianest
+import numdifftools as nd
from scipy.stats import norm
from scipy.signal import fftconvolve
import copy
@@ -341,7 +341,7 @@ def propagate(self,model,lbm=[],ubm=[]):
raise IndexError ('The 2nd and 3rd input arguments must have the same number of elements as the model output.')
# Get jacobian of model to be propagated with respect to parameters
- J,_ = jacobianest(model,parfit)
+ J = np.reshape(nd.Jacobian(model)(parfit),(-1,parfit.size))
# Clip at boundaries
modelfit = np.maximum(modelfit,lbm)
diff --git a/deerlab/correctphase.py b/deerlab/correctphase.py
index be648416c..c6dc438ab 100644
--- a/deerlab/correctphase.py
+++ b/deerlab/correctphase.py
@@ -3,7 +3,7 @@
import scipy.optimize as opt
from deerlab.utils import isempty
-def correctphase(V, Phase = [], fitImagOffset=False, full_output=False):
+def correctphase(V, phase = [], imagoffset=False, full_output=False):
# ==========================================================================
r"""
Phase correction of complex-valued data
@@ -27,16 +27,16 @@ def correctphase(V, Phase = [], fitImagOffset=False, full_output=False):
Real part of the phase corrected dataset.
Vi : ndarray (if full_output==True)
Imaginary part of the phase corrected dataset.
- Phase : float scalar (if full_output==True)
+ phase : float scalar (if full_output==True)
Fitted phase used for correction, in radians.
- ImOffset : float scalar (if full_output==True)
+ imoffset : float scalar (if full_output==True)
Fitted imaginary offset used for correction.
Other Parameters
----------------
- Phase : float scalar
+ phase : float scalar
Phase shift for manual correction, in radians.
- fitImagOffset : boolean
+ imagoffset : boolean
Enables/Disables the fitting and correction of an imaginary offset, by default disabled.
full_output : boolean
If enabled the function will return additional output arguments in a tuple, by default disabled.
@@ -51,34 +51,34 @@ def correctphase(V, Phase = [], fitImagOffset=False, full_output=False):
n = V.shape[0]
# Determine if phase must be fitted or has been passed
- if isempty(Phase):
+ if isempty(phase):
fitPhase = True
else:
fitPhase = False
- Phase = np.atleast_1d(Phase)
- if len(Phase) != Ntraces:
+ phase = np.atleast_1d(phase)
+ if len(phase) != Ntraces:
raise ValueError('The number of input phases must agree with the number of traces.')
# Phase/offset fitting
#-------------------------------------------------------------------------------
ImagOffset = np.zeros(Ntraces)
if fitPhase:
- Phase = np.zeros(Ntraces)
+ phase = np.zeros(Ntraces)
for i in range(Ntraces):
par0 = []
FitRange = np.arange(round(n/8),n) # use only last 7/8 of data for phase/offset correction
V_ = V[FitRange,i]
par0.append(np.mean(np.angle(V_))) # use average phase as initial value
- if fitImagOffset:
+ if imagoffset:
par0.append(np.mean(np.imag(V_))) # use average offset as initial value
fun = lambda par: _imaginarynorm(par,V_)
pars = opt.fmin(fun,par0,maxfun=1e5,maxiter=1e5,disp=False)
- Phase[i] = pars[0]
- if fitImagOffset:
+ phase[i] = pars[0]
+ if imagoffset:
ImagOffset[i] = pars[1]
else:
- if fitImagOffset:
+ if imagoffset:
# Fit only imaginary offset
for i in range(Ntraces):
par0 = 0
@@ -88,7 +88,7 @@ def correctphase(V, Phase = [], fitImagOffset=False, full_output=False):
ImagOffset = ImagOffset*1j
# Apply phase/offset correction
- ph = np.exp(1j*Phase)
+ ph = np.exp(1j*phase)
Vc = (V - ImagOffset)/ph
if Ntraces==1:
@@ -97,10 +97,10 @@ def correctphase(V, Phase = [], fitImagOffset=False, full_output=False):
# Output
Vreal = np.real(Vc)
Vimag = np.imag(Vc)
- Phase = np.angle(ph) # map phase angle to [-pi,pi) interval
+ phase = np.angle(ph) # map phase angle to [-pi,pi) interval
if full_output:
- return Vreal,Vimag,Phase,ImagOffset
+ return Vreal,Vimag,phase,ImagOffset
else:
return Vreal
diff --git a/deerlab/fftspec.py b/deerlab/fftspec.py
index 0be107fb5..3a94d9197 100644
--- a/deerlab/fftspec.py
+++ b/deerlab/fftspec.py
@@ -31,7 +31,7 @@ def fftspec(V,t,mode='abs',zerofilling='auto',apodization=True):
Type of spectrum to be returned ('real','imag','abs'), the default is 'abs'.
zerofilling : scalar
Number of elements in the output FFT spectrum, the default is ``2*len(V)``.
- aposization : boolean
+ apodization : boolean
Use of a Hamming apodization window, the default is True.
"""
diff --git a/deerlab/fitmultimodel.py b/deerlab/fitmultimodel.py
index 642e9ffeb..53787a833 100644
--- a/deerlab/fitmultimodel.py
+++ b/deerlab/fitmultimodel.py
@@ -5,13 +5,14 @@
import copy
import numpy as np
+import numdifftools as nd
from types import FunctionType
import deerlab as dl
-from deerlab.utils import jacobianest, hccm, goodness_of_fit
+from deerlab.utils import hccm, goodness_of_fit
from deerlab.classes import FitResult
def fitmultimodel(V, Kmodel, r, model, maxModels, method='aic', lb=None, ub=None, lbK=None, ubK=None,
- weights=1, normP = True, uqanalysis=True, **kwargs):
+ weights=1, renormalize = True, uqanalysis=True, **kwargs):
r"""
Fits a multi-model parametric distance distribution model to a dipolar signal using separable
non-linear least-squares (SNLLS).
@@ -93,7 +94,7 @@ def fitmultimodel(V, Kmodel, r, model, maxModels, method='aic', lb=None, ub=None
----------------
weights : array_like
Array of weighting coefficients for the individual signals in global fitting, the default is all weighted equally.
- normP : boolean
+ renormalize : boolean
Enable/disable renormalization of the fitted distribution, by default it is enabled.
uqanalysis : boolean
Enable/disable the uncertainty quantification analysis, by default it is enabled.
@@ -272,8 +273,8 @@ def logestimators(V,Vfit,plin,pnonlin,functionals):
Knonlin = lambda par: nonlinmodel(par,Nmodels)
# Box constraints for the model parameters (non-linear parameters)
- nlin_lb = np.matlib.repmat(lb,1,Nmodels)
- nlin_ub = np.matlib.repmat(ub,1,Nmodels)
+ nlin_lb = np.tile(lb,(1,Nmodels))
+ nlin_ub = np.tile(ub,(1,Nmodels))
# Add the box constraints on the non-linear kernel parameters
nlin_lb = np.concatenate((lbK, nlin_lb),axis=None)
@@ -289,7 +290,8 @@ def logestimators(V,Vfit,plin,pnonlin,functionals):
# Separable non-linear least-squares (SNLLS) fit
scale = 1e2
- fit = dl.snlls(V*scale,Knonlin,par0,nlin_lb,nlin_ub,lin_lb,lin_ub, weights=weights, penalty=False, uqanalysis=False,linTolFun=[], linMaxIter=[],**kwargs)
+ fit = dl.snlls(V*scale,Knonlin,par0,nlin_lb,nlin_ub,lin_lb,lin_ub,
+ weights=weights, penalty=False, uqanalysis=False, lin_tol=[], lin_maxiter=[],**kwargs)
pnonlin = fit.nonlin
plin = fit.lin
@@ -341,7 +343,7 @@ def logestimators(V,Vfit,plin,pnonlin,functionals):
res = weights*(Vfit - V)
# Compute the Jacobian
- Jnonlin,_ = jacobianest(lambda p: weights*(Knonlin(p)@plin), pnonlin)
+ Jnonlin = np.reshape(nd.Jacobian(lambda p: weights*(Knonlin(p)@plin))(pnonlin),(-1,pnonlin.size))
Jlin = weights[:,np.newaxis]*Knonlin(pnonlin)
J = np.concatenate((Jnonlin, Jlin),1)
@@ -368,7 +370,7 @@ def logestimators(V,Vfit,plin,pnonlin,functionals):
# If requested re-normalize the distribution
postscale = np.trapz(Pfit,r)
- if normP:
+ if renormalize:
Pfit = Pfit/postscale
fitparam_amp = fitparam_amp/sum(fitparam_amp)
if uqanalysis:
diff --git a/deerlab/fitparamodel.py b/deerlab/fitparamodel.py
index c74815a61..555a13b36 100644
--- a/deerlab/fitparamodel.py
+++ b/deerlab/fitparamodel.py
@@ -4,12 +4,15 @@
# Copyright(c) 2019-2020: Luis Fabregas, Stefan Stoll and other contributors.
import numpy as np
-from deerlab.utils import isempty, multistarts, jacobianest, hccm, parse_multidatasets, goodness_of_fit
+import numdifftools as nd
+from deerlab.utils import isempty, multistarts, hccm, parse_multidatasets, goodness_of_fit
from deerlab.classes import UncertQuant, FitResult
from scipy.optimize import least_squares
import warnings
-def fitparamodel(V, model, par0=[],lb=[],ub=[], weights = 1, MultiStart=1, tolFun=1e-10, maxFunEvals=5000, maxIter = 3000, rescale=True, uqanalysis=True, covmatrix=[]):
+def fitparamodel(V, model, par0=[],lb=[],ub=[], weights = 1,
+ multistart=1, tol=1e-10, maxeval=5000, maxiter = 3000,
+ rescale=True, uqanalysis=True, covmatrix=[]):
r""" Fits the dipolar signal(s) to a parametric model using non-linear least-squares.
Parameters
@@ -60,11 +63,11 @@ def fitparamodel(V, model, par0=[],lb=[],ub=[], weights = 1, MultiStart=1, tolFu
Number of starting points for global optimization, the default is 1.
uqanalysis : boolean
Enable/disable the uncertainty quantification analysis, by default it is enabled.
- tolFun : scalar
+ tol : scalar
Optimizer function tolerance, the default is 1e-10.
- maxFunEvals : scalar
+ maxeval : scalar
Maximum number of optimizer iterations, the default is 5000.
- maxIter : scalar
+ maxiter : scalar
Maximum number of optimizer iterations, the default is 3000.
covmatrix : array_like with shape(n,n)
Covariance matrix of the noise in the dataset(s). If not specified it is automatically computed.
@@ -135,9 +138,9 @@ def Vmodel(par):
raise ValueError('Lower bound values cannot be larger than upper bound values.')
# Preprare multiple start global optimization if requested
- if MultiStart>1 and unboundedparams:
- raise ValueError('Multistart optimization cannot be used with unconstrained parameters.')
- multistarts_par0 = multistarts(MultiStart,par0,lb,ub)
+ if multistart>1 and unboundedparams:
+ raise ValueError('multistart optimization cannot be used with unconstrained parameters.')
+ multistarts_par0 = multistarts(multistart,par0,lb,ub)
def lsqresiduals(p):
# -------------------------------------------------------------------------------
@@ -153,7 +156,7 @@ def lsqresiduals(p):
# Check if there are invalid values...
if any(np.isnan(Vsim)) or any(np.isinf(Vsim)):
- res = np.zeros_like(Vsim) # ...can happen when jacobianest() evaluates outside of bounds
+ res = np.zeros_like(Vsim) # ...can happen when Jacobian is evaluated outside of bounds
return res
# Otherwise if requested, compute the scale of the signal via linear LSQ
@@ -175,7 +178,7 @@ def lsqresiduals(p):
sols = []
for par0 in multistarts_par0:
# Solve the non-linear least squares (NLLS) problem
- sol = least_squares(lsqresiduals ,par0, bounds=(lb,ub), max_nfev=int(maxIter), ftol=tolFun, method='dogbox')
+ sol = least_squares(lsqresiduals ,par0, bounds=(lb,ub), max_nfev=int(maxiter), ftol=tol, method='dogbox')
sols.append(sol)
parfits.append(sol.x)
fvals.append(sol.cost)
@@ -208,7 +211,7 @@ def lsqresiduals(p):
# of the negative log-likelihood
with warnings.catch_warnings():
warnings.simplefilter('ignore')
- J,_ = jacobianest(lsqresiduals,parfit)
+ J = np.reshape(nd.Jacobian(lsqresiduals)(parfit),(-1,parfit.size))
# Estimate the heteroscedasticity-consistent covariance matrix
if isempty(covmatrix):
diff --git a/deerlab/fitregmodel.py b/deerlab/fitregmodel.py
index 4fc101496..29f037bb2 100644
--- a/deerlab/fitregmodel.py
+++ b/deerlab/fitregmodel.py
@@ -5,7 +5,6 @@
import numpy as np
from deerlab.nnls import fnnls, cvxnnls, nnlsbpp
-from scipy.optimize import nnls
import deerlab as dl
import copy
from deerlab.utils import hccm, goodness_of_fit
diff --git a/deerlab/fitsignal.py b/deerlab/fitsignal.py
index ffaf69dba..044b62ef1 100644
--- a/deerlab/fitsignal.py
+++ b/deerlab/fitsignal.py
@@ -4,6 +4,7 @@
# Copyright(c) 2019-2020: Luis Fabregas, Stefan Stoll and other contributors.
import numpy as np
+import numdifftools as nd
import types
import copy
import matplotlib.pyplot as plt
@@ -11,11 +12,11 @@
from deerlab.classes import UncertQuant, FitResult
from deerlab.bg_models import bg_hom3d
from deerlab.ex_models import ex_4pdeer
-from deerlab.utils import isempty, goodness_of_fit, jacobianest
+from deerlab.utils import isempty, goodness_of_fit
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],
- weights=1, uqanalysis=True, display = False):
+ weights=1, uqanalysis=True, display = False, regparam='aic', regtype = 'tikhonov'):
r"""
Fits a dipolar model to the experimental signal V with time axis t, using
distance axis r. The model is specified by the distance distribution (dd),
@@ -128,6 +129,34 @@ def fitsignal(Vexp, t, r, dd_model='P', bg_model=bg_hom3d, ex_model=ex_4pdeer,
Array of weighting coefficients for the individual signals in global fitting,
the default is all weighted equally.
If not specified all datasets are weighted equally.
+ regParam (str or scalar):
+ Method for the automatic selection of the optimal regularization parameter:
+
+ * ``'lr'`` - L-curve minimum-radius method (LR)
+ * ``'lc'`` - L-curve maximum-curvature method (LC)
+ * ``'cv'`` - Cross validation (CV)
+ * ``'gcv'`` - Generalized Cross Validation (GCV)
+ * ``'rgcv'`` - Robust Generalized Cross Validation (rGCV)
+ * ``'srgcv'`` - Strong Robust Generalized Cross Validation (srGCV)
+ * ``'aic'`` - Akaike information criterion (AIC)
+ * ``'bic'`` - Bayesian information criterion (BIC)
+ * ``'aicc'`` - Corrected Akaike information criterion (AICC)
+ * ``'rm'`` - Residual method (RM)
+ * ``'ee'`` - Extrapolated Error (EE)
+ * ``'ncp'`` - Normalized Cumulative Periodogram (NCP)
+ * ``'gml'`` - Generalized Maximum Likelihood (GML)
+ * ``'mcl'`` - Mallows' C_L (MCL)
+ The regularization parameter can be manually specified by passing a scalar value
+ instead of a string. The default ``'aic'``.
+
+ regtype : string
+ Regularization functional type:
+
+ * ``'tikhonov'`` - Tikhonov regularizaton
+ * ``'tv'`` - Total variation regularization
+ * ``'huber'`` - Huber regularization
+ The default is ``'tikhonov'``.
+
uqanalysis : boolean
Enable/disable the uncertainty quantification analysis, by default it is enabled.
display : boolean
@@ -168,9 +197,6 @@ def fitsignal(Vexp, t, r, dd_model='P', bg_model=bg_hom3d, ex_model=ex_4pdeer,
"""
# Default optional settings
- regtype = 'tikhonov'
- regparam = 'aic'
- DisplayResults = display
normP = True
# Make inputs into a list if just a singal is passed
@@ -317,7 +343,7 @@ def splituq(full_uq):
bgsubcovmat = paruq.covmat[np.ix_(bgidx[jj],bgidx[jj])]
paruq_bg.append( UncertQuant('covariance',parfit_[bgidx[jj]],bgsubcovmat,lb[bgidx[jj]],ub[bgidx[jj]]))
else:
- paruq_bg.append([])
+ paruq_bg.append([None])
# Experiment parameters uncertainty
# ----------------------------------
@@ -326,7 +352,7 @@ def splituq(full_uq):
exsubcovmat = paruq.covmat[np.ix_(exidx[jj],exidx[jj])]
paruq_ex.append( UncertQuant('covariance',parfit_[exidx[jj]],exsubcovmat,lb[exidx[jj]],ub[exidx[jj]]))
else:
- paruq_ex.append([])
+ paruq_ex.append([None])
# Distribution parameters uncertainty
# ------------------------------------
@@ -334,7 +360,7 @@ def splituq(full_uq):
ddsubcovmat = paruq.covmat[np.ix_(ddidx,ddidx)]
paruq_dd = UncertQuant('covariance',parfit_[ddidx],ddsubcovmat,lb[ddidx],ub[ddidx])
else:
- paruq_dd = []
+ paruq_dd = [None]
# Distance distribution uncertainty
# ----------------------------------
@@ -351,23 +377,28 @@ def splituq(full_uq):
if includeExperiment[jj]:
Bfit_uq.append( paruq.propagate(lambda par:multiPathwayModel(par)[1][jj]))
else:
- Bfit_uq.append([])
+ Bfit_uq.append([None])
# Dipolar signal uncertainty
# --------------------------
for jj in range(nSignals):
if includeForeground and parametricDistribution:
- # Simple parametric model error propagation
+ # Full parametric signal
Vmodel = lambda par: multiPathwayModel(par)[0][jj]@Pfcn(par[ddidx])
Vfit_uq.append( paruq.propagate(Vmodel))
+ elif includeForeground and np.all(~includeExperiment & ~includeBackground):
+ # Dipola evolution function
+ J = Ks[jj]
+ Vcovmat = J@covmat@J.T
+ Vfit_uq.append( UncertQuant('covariance',Vfit[jj],Vcovmat,[],[]))
elif includeForeground:
- # Use special structure to speed up propagation for
- # parameter-free case instead of .propagate()
- J = np.concatenate((jacobianest(lambda par: multiPathwayModel(par[paramidx])[0][jj]@Pfit,parfit_)[0], Kfit[jj]),1)
+ # Parametric signal with parameter-free distribution
+ Jnonlin = np.reshape(nd.Jacobian(lambda par: multiPathwayModel(par[paramidx])[0][jj]@Pfit)(parfit_),(-1,parfit_.size))
+ J = np.concatenate((Jnonlin, Kfit[jj]),1)
Vcovmat = J@covmat@J.T
Vfit_uq.append( UncertQuant('covariance',Vfit[jj],Vcovmat,[],[]))
else:
- Vfit_uq.append([])
+ Vfit_uq.append([None])
return Vfit_uq,Pfit_uq,Bfit_uq,paruq_bg,paruq_ex,paruq_dd
# =========================================================================
@@ -381,7 +412,7 @@ def splituq(full_uq):
Ks = [dl.dipolarkernel(ts,r) for ts in t]
# Linear regularization fit
- fit = dl.fitregmodel(Vexp,Ks,r,regtype,regparam, weights=weights,uqanalysis=uqanalysis)
+ fit = dl.fitregmodel(Vexp,Ks,r,regtype,regparam, weights=weights,uqanalysis=False)
Pfit = fit.P
Pfit_uq = fit.uncertainty
scales = fit.scale
@@ -391,8 +422,10 @@ def splituq(full_uq):
Bfit = [np.ones_like(V) for V in Vexp]
# No parameters
- parfit_,Vfit_uq,Bfit_uq,paruq_bg,paruq_dd,paruq_ex = np.atleast_1d([[None]*nSignals for _ in range(6)])
-
+ parfit_ = np.asarray([None])
+ if uqanalysis:
+ Vfit_uq, Pfit_uq, Bfit_uq, paruq_bg, paruq_ex, paruq_dd = splituq(Pfit_uq)
+
elif OnlyParametric:
# Prepare the full-parametric model
@@ -429,7 +462,8 @@ def splituq(full_uq):
Vexp = [Vexp[i]/prescales[i] for i in range(nSignals)]
# Separable non-linear least squares (SNNLS)
- fit = dl.snlls(Vexp,lambda par: multiPathwayModel(par)[0],par0,lb,ub,lbl, regparam=regparam,linMaxIter=[],uqanalysis=uqanalysis,linTolFun=[],weights=weights)
+ fit = dl.snlls(Vexp,lambda par: multiPathwayModel(par)[0],par0,lb,ub,lbl,
+ regparam=regparam, lin_maxiter=[], uqanalysis=uqanalysis, lin_tol=[], weights=weights)
parfit_ = fit.nonlin
Pfit = fit.lin
snlls_uq = fit.uncertainty
@@ -554,7 +588,7 @@ def _display_results():
# Plotting
# --------
- if DisplayResults:
+ if display:
_display_results()
# Return numeric arrays and not lists if there is only one signal
diff --git a/deerlab/regparamrange.py b/deerlab/regparamrange.py
index a5040839b..8f4655fe7 100644
--- a/deerlab/regparamrange.py
+++ b/deerlab/regparamrange.py
@@ -40,6 +40,7 @@ def regparamrange(K,L,noiselvl=0,logres=0.1):
DerivativeOrder = L.shape[1] - L.shape[0] # get order of derivative (=number of inf in singval)
singularValues = singularValues[0:len(singularValues)-DerivativeOrder] # remove inf
singularValues = singularValues[::-1] # sort in decreasing order
+ singularValues = singularValues[singularValues>0] # remove zeros
lgsingularValues = np.log10(singularValues)
# Calculate range based on singular values
diff --git a/deerlab/snlls.py b/deerlab/snlls.py
index 56f92e502..0d18c727c 100644
--- a/deerlab/snlls.py
+++ b/deerlab/snlls.py
@@ -1,18 +1,19 @@
import copy
import numpy as np
+import numdifftools as nd
from scipy.optimize import least_squares, lsq_linear
from numpy.linalg import solve
# Import DeerLab depencies
import deerlab as dl
-from deerlab.utils import jacobianest, goodness_of_fit, hccm, isempty
+from deerlab.utils import goodness_of_fit, hccm, isempty
from deerlab.nnls import cvxnnls, fnnls, nnlsbpp
from deerlab.classes import UncertQuant, FitResult
def snlls(y, Amodel, par0, lb=None, ub=None, lbl=None, ubl=None, nnlsSolver='cvx', penalty=None, weights=1,
- regtype='tikhonov', regparam='aic', multiStarts=1, regOrder=2, alphaOptThreshold=1e-3,
- nonLinTolFun=1e-9, nonLinMaxIter=1e8, linTolFun=1e-15, linMaxIter=1e4, huberparam=1.35,
+ regtype='tikhonov', regparam='aic', multistart=1, regorder=2, alphareopt=1e-3,
+ nonlin_tol=1e-9, nonlin_maxiter=1e8, lin_tol=1e-15, lin_maxiter=1e4, huberparam=1.35,
uqanalysis=True):
r""" Separable Non-linear Least Squares Solver
@@ -79,7 +80,7 @@ def snlls(y, Amodel, par0, lb=None, ub=None, lbl=None, ubl=None, nnlsSolver='cvx
* ``'huber'`` - Huber regularization
The default is ``'tikhonov'``.
- regOrder (scalar,int)
+ regorder (scalar,int)
Order of the regularization operator
regParam (str or scalar):
Method for the automatic selection of the optimal regularization parameter:
@@ -101,7 +102,7 @@ def snlls(y, Amodel, par0, lb=None, ub=None, lbl=None, ubl=None, nnlsSolver='cvx
The regularization parameter can be manually specified by passing a scalar value
instead of a string. The default ``'aic'``.
- alphaOptThreshold : float scalar
+ alphareopt : float scalar
Relative parameter change threshold for reoptimizing the regularization parameter
when using a selection method, the default is 1e-3.
nnlsSolver : string
@@ -114,15 +115,15 @@ def snlls(y, Amodel, par0, lb=None, ub=None, lbl=None, ubl=None, nnlsSolver='cvx
weights : array_like
Array of weighting coefficients for the individual signals in global fitting,
the default is all weighted equally.
- multiStarts : int scalar
+ multistart : int scalar
Number of starting points for global optimization, the default is 1.
- nonLinMaxIter : float scalar
+ nonlin_maxiter : float scalar
Non-linear solver maximal number of iterations, the default is 1e8.
- nonLinTolFun : float scalar
+ nonlin_tol : float scalar
Non-linear solver function tolerance, the default is 1e-9.
- linMaxIter : float scalar
+ lin_maxiter : float scalar
Linear solver maximal number of iterations, the default is 1e4.
- linTolFun : float scalar
+ lin_tol : float scalar
Linear solver function tolerance, the default is 1e-15.
uqanalysis : boolean
Enable/disable the uncertainty quantification analysis, by default it is enabled.
@@ -227,8 +228,8 @@ def snlls(y, Amodel, par0, lb=None, ub=None, lbl=None, ubl=None, nnlsSolver='cvx
# Use an arbitrary axis
ax = np.arange(1, Nlin+1)
# Get regularization operator
- regOrder = np.minimum(Nlin-1, regOrder)
- L = dl.regoperator(ax, regOrder)
+ regorder = np.minimum(Nlin-1, regorder)
+ L = dl.regoperator(ax, regorder)
else:
L = np.eye(Nlin, Nlin)
@@ -247,11 +248,11 @@ def snlls(y, Amodel, par0, lb=None, ub=None, lbl=None, ubl=None, nnlsSolver='cvx
elif linearConstrained and nonNegativeOnly:
# Non-negative linear LSQ
if nnlsSolver is 'fnnls':
- linSolver = lambda AtA, Aty: fnnls(AtA, Aty, tol=linTolFun, maxiter=linMaxIter)
+ linSolver = lambda AtA, Aty: fnnls(AtA, Aty, tol=lin_tol, maxiter=lin_maxiter)
elif nnlsSolver is 'nnlsbpp':
linSolver = lambda AtA, Aty: nnlsbpp(AtA, Aty, np.linalg.solve(AtA, Aty))
elif nnlsSolver is 'cvx':
- linSolver = lambda AtA, Aty: cvxnnls(AtA, Aty, tol=linTolFun, maxiter=linMaxIter)
+ linSolver = lambda AtA, Aty: cvxnnls(AtA, Aty, tol=lin_tol, maxiter=lin_maxiter)
parseResult = lambda result: result
# ----------------------------------------------------------
@@ -277,12 +278,12 @@ def ResidualsFcn(p):
if includePenalty:
if type(regparam) is str:
# If the parameter vector has not changed by much...
- if check and all(abs(par_prev-p)/p < alphaOptThreshold):
+ if check and all(abs(par_prev-p)/p < alphareopt):
# ...use the alpha optimized in the previous iteration
alpha = regparam_prev
else:
# ...otherwise optimize with current settings
- alpha = dl.selregparam(y, A, ax, regtype, regparam, regorder=regOrder)
+ alpha = dl.selregparam(y, A, ax, regtype, regparam, regorder=regorder)
check = True
else:
# Fixed regularization parameter
@@ -318,9 +319,9 @@ def ResidualsFcn(p):
# Preprare multiple start global optimization if requested
- if multiStarts > 1 and not nonLinearConstrained:
+ if multistart > 1 and not nonLinearConstrained:
raise TypeError('Multistart optimization cannot be used with unconstrained non-linear parameters.')
- multiStartPar0 = dl.utils.multistarts(multiStarts, par0, lb, ub)
+ multiStartPar0 = dl.utils.multistarts(multistart, par0, lb, ub)
# Pre-allocate containers for multi-start run
fvals, nonlinfits, linfits, sols = ([] for _ in range(4))
@@ -328,7 +329,7 @@ def ResidualsFcn(p):
# Multi-start global optimization
for par0 in multiStartPar0:
# Run the non-linear solver
- sol = least_squares(ResidualsFcn, par0, bounds=(lb, ub), max_nfev=int(nonLinMaxIter), ftol=nonLinTolFun)
+ sol = least_squares(ResidualsFcn, par0, bounds=(lb, ub), max_nfev=int(nonlin_maxiter), ftol=nonlin_tol)
nonlinfits.append(sol.x)
linfits.append(linfit)
fvals.append(sol.cost)
@@ -349,7 +350,7 @@ def ResidualsFcn(p):
# Compute the Jacobian for the linear and non-linear parameters
fcn = lambda p: Amodel(p)@linfit
- Jnonlin, _ = jacobianest(fcn,nonlinfit)
+ Jnonlin = np.reshape(nd.Jacobian(fcn)(nonlinfit),(-1,nonlinfit.size))
Jlin = Afit
J = np.concatenate((Jnonlin, Jlin),1)
diff --git a/deerlab/utils/__init__.py b/deerlab/utils/__init__.py
index ef60b41e5..eab2fa7e2 100644
--- a/deerlab/utils/__init__.py
+++ b/deerlab/utils/__init__.py
@@ -1,6 +1,5 @@
# __init__.py
from .exvolume_alphas import *
-from .jacobianest import jacobianest
from .utils import *
from .gof import goodness_of_fit
diff --git a/deerlab/utils/jacobianest.py b/deerlab/utils/jacobianest.py
deleted file mode 100644
index 1b0119dd8..000000000
--- a/deerlab/utils/jacobianest.py
+++ /dev/null
@@ -1,179 +0,0 @@
-import numpy as np
-import scipy
-import scipy.optimize as opt
-import numpy.matlib
-
-def jacobianest(fcn_,x0):
- r"""
- Jacobian numerical estimation
- =============================
-
- Estimate of the Jacobian matrix of a vector valued function of n variables
-
- Usage:
- [jac,err] = jacobianest(fun,x0)
-
-
- Arguments:
- fun - (vector valued) analytical function to differentiate.
- fun must be a function of the vector or array x0.
-
- x0 - vector location at which to differentiate fun
- If x0 is an nxm array, then fun is assumed to be
- a function of n*m variables.
-
-
- Output:
- jac - array of first partial derivatives of fun.
- Assuming that x0 is a vector of length p
- and fun returns a vector of length n, then
- jac will be an array of size (n,p)
-
- err - vector of error estimates corresponding to
- each partial derivative in jac.
-
- Source:
- Adaptive Robust Numerical Differentiation
- John D'Errico (2020)
- jacobianest.m version 1.6.1
- https://www.mathworks.com/matlabcentral/fileexchange/13490-adaptive-robust-numerical-differentiation)
- MATLAB Central File Exchange.
- """
-
- # subfunction - swap vector elements
- # ----------------------------------------------------------------------
- def swapelement(vec,ind,val):
- """
- Swaps val as element ind, into the vector vec
- """
- vec[ind] = val
- return vec
- # ----------------------------------------------------------------------
-
- # subfunction - romberg extrapolation
- # ----------------------------------------------------------------------
- def rombextrap(StepRatio,der_init,rombexpon):
- """
- Romberg extrapolation for each estimate
-
- StepRatio - Ratio decrease in step
- der_init - initial derivative estimates
- rombexpon - higher order terms to cancel using the romberg step
-
- der_romb - derivative estimates returned
- errest - error estimates
- amp - noise amplification factor due to the romberg step
- """
- srinv = 1/StepRatio
- # do nothing if no romberg terms
- nexpon = len(rombexpon)
- rmat = np.ones((nexpon+2,nexpon+1))
- # two romberg terms
- rmat[1,1:3] = np.power(srinv,rombexpon)
- rmat[2,1:3] = np.power(srinv,2*rombexpon)
- rmat[3,1:3] = np.power(srinv,3*rombexpon)
- # qr factorization used for the extrapolation as well
- # as the uncertainty estimates
- qromb,rromb = np.linalg.qr(rmat,'reduced')
- # the noise amplification is further amplified by the Romberg step.
- # amp = cond(rromb)
- # this does the extrapolation to a zero step size.
- ne = len(der_init)
- rhs = vec2mat(der_init,nexpon+2,ne - (nexpon+2))
- rombcoefs = scipy.linalg.solve(rromb,qromb.T@rhs)
- der_romb = rombcoefs[0,:].T
- # uncertainty estimate of derivative prediction
- s = np.sqrt(sum((rhs - rmat@rombcoefs)**2,0))
- rinv = scipy.linalg.solve(rromb,np.eye(nexpon+1))
- cov1 = np.sum(rinv**2,1)
- errest = s.T*12.7062047361747*np.sqrt(cov1[0])
-
- return der_romb, errest
- # ----------------------------------------------------------------------
-
- # subfunction - vec2mat
- # ----------------------------------------------------------------------
- def vec2mat(vec,n,m):
- # forms the matrix M, such that M(i,j) = vec(i+j-1)
- i,j = np.mgrid[range(n),range(-1,m)]
- ind = i+j
- mat = vec[ind]
- if n==1:
- mat = mat.T
- return mat
- # ----------------------------------------------------------------------
-
- nx = len(x0)
- MaxStep = 2
- StepRatio = 2.0000001
-
- # Patch the input function to handle invalid values in bounded functions
- fun = lambda args: _detect_invalid_values(fcn_,args)
-
- # Get fun at the center point
- f0 = fun(x0)
- n = len(f0)
- if n==0:
- # Empty begets empty
- jac = np.zeros((0,nx))
- err = jac
- return jac, err
- relativedelta = MaxStep*StepRatio**np.arange(0,-25,-1)
- nsteps = len(relativedelta)
-
- # total number of derivatives we will need to take
- jac = np.zeros((n,nx))
- err = jac
- for i in range(nx):
- x0_i = x0[i]
- if x0_i != 0:
- delta = x0_i*relativedelta
- else:
- delta = relativedelta
-
- # evaluate at each step, centered around x0_i
- # difference to give a second order estimate
- fdel = np.zeros((n,nsteps))
- for j in range(nsteps):
- fdif = fun(swapelement(x0,i,x0_i + delta[j])) - fun(swapelement(x0,i,x0_i - delta[j]))
- fdel[:,j] = fdif[:]
-
-
- # these are pure second order estimates of the
- # first derivative, for each trial delta.
- derest = fdel*np.matlib.repmat(0.5/delta,n,1)
-
- # The error term on these estimates has a second order
- # component, but also some 4th and 6th order terms in it.
- # Use Romberg exrapolation to improve the estimates to
- # 6th order, as well as to provide the error estimate.
-
- # loop here, as rombextrap coupled with the trimming
- # will get complicated otherwise.
- for j in range(n):
- der_romb,errest = rombextrap(StepRatio,derest[j,:],np.asarray([2, 4]))
-
- # trim off 3 estimates at each end of the scale
- nest = len(der_romb)
- trim = np.concatenate((np.arange(3), nest+(np.arange(-3,0))))
- der_romb = np.sort(der_romb)
- tags = np.argsort(der_romb)
- der_romb = np.delete(der_romb,trim)
- tags = np.delete(tags,trim)
-
- errest = errest[tags]
-
- # now pick the estimate with the lowest predicted error
- err[j,i] = np.min(errest)
- ind = np.argmin(errest)
- jac[j,i] = der_romb[ind]
-
- return jac, err
-# ----------------------------------------------------------------------
-
-def _detect_invalid_values(fcn,args):
- out = fcn(args)
- out = np.atleast_1d(out)
- if np.any(np.isnan(out)) or np.any(np.isinf(out)) or not np.all(np.isreal(out)):
- out = np.zeros_like(out)
- return out
\ No newline at end of file
diff --git a/docsrc/source/auto_examples/auto_examples_jupyter.zip b/docsrc/source/auto_examples/auto_examples_jupyter.zip
deleted file mode 100644
index 9b28fb5d5..000000000
Binary files a/docsrc/source/auto_examples/auto_examples_jupyter.zip and /dev/null differ
diff --git a/docsrc/source/auto_examples/auto_examples_python.zip b/docsrc/source/auto_examples/auto_examples_python.zip
deleted file mode 100644
index f534cd394..000000000
Binary files a/docsrc/source/auto_examples/auto_examples_python.zip and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_analyzing_pake_pattern_001.png b/docsrc/source/auto_examples/images/sphx_glr_plot_analyzing_pake_pattern_001.png
deleted file mode 100644
index 9707e540b..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_analyzing_pake_pattern_001.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_analyzing_pake_pattern_002.png b/docsrc/source/auto_examples/images/sphx_glr_plot_analyzing_pake_pattern_002.png
deleted file mode 100644
index 347f9e4c5..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_analyzing_pake_pattern_002.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_analyzing_pake_pattern_003.png b/docsrc/source/auto_examples/images/sphx_glr_plot_analyzing_pake_pattern_003.png
deleted file mode 100644
index 33c5abf87..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_analyzing_pake_pattern_003.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_bootstrapped_parameter_distributions_001.png b/docsrc/source/auto_examples/images/sphx_glr_plot_bootstrapped_parameter_distributions_001.png
deleted file mode 100644
index e5fb5e5a7..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_bootstrapped_parameter_distributions_001.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_comparing_uncertainties_for_regularization_001.png b/docsrc/source/auto_examples/images/sphx_glr_plot_comparing_uncertainties_for_regularization_001.png
deleted file mode 100644
index e27797b4e..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_comparing_uncertainties_for_regularization_001.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_comparing_uncertainties_for_regularization_002.png b/docsrc/source/auto_examples/images/sphx_glr_plot_comparing_uncertainties_for_regularization_002.png
deleted file mode 100644
index 6735b4688..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_comparing_uncertainties_for_regularization_002.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_emulating_deeranalysis_workflow_001.png b/docsrc/source/auto_examples/images/sphx_glr_plot_emulating_deeranalysis_workflow_001.png
deleted file mode 100644
index a0c9321bd..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_emulating_deeranalysis_workflow_001.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_emulating_deeranalysis_workflow_002.png b/docsrc/source/auto_examples/images/sphx_glr_plot_emulating_deeranalysis_workflow_002.png
deleted file mode 100644
index b48c2a90e..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_emulating_deeranalysis_workflow_002.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_extracting_gauss_constraints_001.png b/docsrc/source/auto_examples/images/sphx_glr_plot_extracting_gauss_constraints_001.png
deleted file mode 100644
index 44b4db284..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_extracting_gauss_constraints_001.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_extracting_gauss_constraints_002.png b/docsrc/source/auto_examples/images/sphx_glr_plot_extracting_gauss_constraints_002.png
deleted file mode 100644
index 67ca14127..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_extracting_gauss_constraints_002.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_fitting_4pdeer_001.png b/docsrc/source/auto_examples/images/sphx_glr_plot_fitting_4pdeer_001.png
deleted file mode 100644
index ebe257e58..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_fitting_4pdeer_001.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_fitting_5pdeer_001.png b/docsrc/source/auto_examples/images/sphx_glr_plot_fitting_5pdeer_001.png
deleted file mode 100644
index 824a1d316..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_fitting_5pdeer_001.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_fitting_custom_kernel_with_snlls_001.png b/docsrc/source/auto_examples/images/sphx_glr_plot_fitting_custom_kernel_with_snlls_001.png
deleted file mode 100644
index 422672131..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_fitting_custom_kernel_with_snlls_001.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_fitting_mixed_model_001.png b/docsrc/source/auto_examples/images/sphx_glr_plot_fitting_mixed_model_001.png
deleted file mode 100644
index 5f4a144a0..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_fitting_mixed_model_001.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_globalfits_local_and_global_parameters_001.png b/docsrc/source/auto_examples/images/sphx_glr_plot_globalfits_local_and_global_parameters_001.png
deleted file mode 100644
index 4d0a7a3d0..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_globalfits_local_and_global_parameters_001.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_multigauss_fitting_4pdeer_001.png b/docsrc/source/auto_examples/images/sphx_glr_plot_multigauss_fitting_4pdeer_001.png
deleted file mode 100644
index e2f5ed490..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_multigauss_fitting_4pdeer_001.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_param_uncertainty_propagation_001.png b/docsrc/source/auto_examples/images/sphx_glr_plot_param_uncertainty_propagation_001.png
deleted file mode 100644
index 977115b50..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_param_uncertainty_propagation_001.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_pseudotitration_parameter_free_001.png b/docsrc/source/auto_examples/images/sphx_glr_plot_pseudotitration_parameter_free_001.png
deleted file mode 100644
index ee8303067..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_pseudotitration_parameter_free_001.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/sphx_glr_plot_selecting_an_optimal_model_001.png b/docsrc/source/auto_examples/images/sphx_glr_plot_selecting_an_optimal_model_001.png
deleted file mode 100644
index 4d5348335..000000000
Binary files a/docsrc/source/auto_examples/images/sphx_glr_plot_selecting_an_optimal_model_001.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/thumb/sphx_glr_example_fitting_5pdeer_thumb.png b/docsrc/source/auto_examples/images/thumb/sphx_glr_example_fitting_5pdeer_thumb.png
deleted file mode 100644
index 233f8e605..000000000
Binary files a/docsrc/source/auto_examples/images/thumb/sphx_glr_example_fitting_5pdeer_thumb.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_analyzing_pake_pattern_thumb.png b/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_analyzing_pake_pattern_thumb.png
deleted file mode 100644
index ac93b7c0d..000000000
Binary files a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_analyzing_pake_pattern_thumb.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_bootstrapped_parameter_distributions_thumb.png b/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_bootstrapped_parameter_distributions_thumb.png
deleted file mode 100644
index b660bb76b..000000000
Binary files a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_bootstrapped_parameter_distributions_thumb.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_comparing_uncertainties_for_regularization_thumb.png b/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_comparing_uncertainties_for_regularization_thumb.png
deleted file mode 100644
index cc772a512..000000000
Binary files a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_comparing_uncertainties_for_regularization_thumb.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_emulating_deeranalysis_workflow_thumb.png b/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_emulating_deeranalysis_workflow_thumb.png
deleted file mode 100644
index e5530c4d7..000000000
Binary files a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_emulating_deeranalysis_workflow_thumb.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_extracting_gauss_constraints_thumb.png b/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_extracting_gauss_constraints_thumb.png
deleted file mode 100644
index 9777cd7f7..000000000
Binary files a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_extracting_gauss_constraints_thumb.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_fitting_4pdeer_thumb.png b/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_fitting_4pdeer_thumb.png
deleted file mode 100644
index a1745b141..000000000
Binary files a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_fitting_4pdeer_thumb.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_fitting_5pdeer_thumb.png b/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_fitting_5pdeer_thumb.png
deleted file mode 100644
index f7d3e42fb..000000000
Binary files a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_fitting_5pdeer_thumb.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_fitting_custom_kernel_with_snlls_thumb.png b/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_fitting_custom_kernel_with_snlls_thumb.png
deleted file mode 100644
index 3b3e93615..000000000
Binary files a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_fitting_custom_kernel_with_snlls_thumb.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_fitting_mixed_model_thumb.png b/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_fitting_mixed_model_thumb.png
deleted file mode 100644
index 87275eebd..000000000
Binary files a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_fitting_mixed_model_thumb.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_globalfits_local_and_global_parameters_thumb.png b/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_globalfits_local_and_global_parameters_thumb.png
deleted file mode 100644
index 0d8581c91..000000000
Binary files a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_globalfits_local_and_global_parameters_thumb.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_multigauss_fitting_4pdeer_thumb.png b/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_multigauss_fitting_4pdeer_thumb.png
deleted file mode 100644
index b91acca56..000000000
Binary files a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_multigauss_fitting_4pdeer_thumb.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_param_uncertainty_propagation_thumb.png b/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_param_uncertainty_propagation_thumb.png
deleted file mode 100644
index cc782edb2..000000000
Binary files a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_param_uncertainty_propagation_thumb.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_pseudotitration_parameter_free_thumb.png b/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_pseudotitration_parameter_free_thumb.png
deleted file mode 100644
index bebfa290c..000000000
Binary files a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_pseudotitration_parameter_free_thumb.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_selecting_an_optimal_model_thumb.png b/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_selecting_an_optimal_model_thumb.png
deleted file mode 100644
index 92bf5eed3..000000000
Binary files a/docsrc/source/auto_examples/images/thumb/sphx_glr_plot_selecting_an_optimal_model_thumb.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/images/thumb/sphx_glr_plt_multigauss_fitting_4pdeer_thumb.png b/docsrc/source/auto_examples/images/thumb/sphx_glr_plt_multigauss_fitting_4pdeer_thumb.png
deleted file mode 100644
index 233f8e605..000000000
Binary files a/docsrc/source/auto_examples/images/thumb/sphx_glr_plt_multigauss_fitting_4pdeer_thumb.png and /dev/null differ
diff --git a/docsrc/source/auto_examples/index.rst b/docsrc/source/auto_examples/index.rst
deleted file mode 100644
index bb99af580..000000000
--- a/docsrc/source/auto_examples/index.rst
+++ /dev/null
@@ -1,336 +0,0 @@
-:orphan:
-
-
-
-.. _sphx_glr_auto_examples:
-
-Examples
-=========================================
-
-Here is a collection of example scripts for the use of DeerLab.
-
-.. note:: Couldn't find what you were looking for? `Add a request `_ for a new example/tutorial and it will considered for the next release.
-
-
-
-.. raw:: html
-
-
-
-.. only:: html
-
- .. figure:: /auto_examples/images/thumb/sphx_glr_plot_fitting_4pdeer_thumb.png
- :alt: Basic fitting of a 4-pulse DEER signal, non-parametric distribution
-
- :ref:`sphx_glr_auto_examples_plot_fitting_4pdeer.py`
-
-.. raw:: html
-
-
-
-
-.. toctree::
- :hidden:
-
- /auto_examples/plot_fitting_4pdeer
-
-.. raw:: html
-
-
-
-.. only:: html
-
- .. figure:: /auto_examples/images/thumb/sphx_glr_plot_fitting_5pdeer_thumb.png
- :alt: Fitting a 5-pulse DEER signal with a parameter-free distribution
-
- :ref:`sphx_glr_auto_examples_plot_fitting_5pdeer.py`
-
-.. raw:: html
-
-
-
-
-.. toctree::
- :hidden:
-
- /auto_examples/plot_fitting_5pdeer
-
-.. raw:: html
-
-
-
-.. only:: html
-
- .. figure:: /auto_examples/images/thumb/sphx_glr_plot_fitting_mixed_model_thumb.png
- :alt: Fitting a mixed distance-distribution model
-
- :ref:`sphx_glr_auto_examples_plot_fitting_mixed_model.py`
-
-.. raw:: html
-
-
-
-
-.. toctree::
- :hidden:
-
- /auto_examples/plot_fitting_mixed_model
-
-.. raw:: html
-
-
-
-.. only:: html
-
- .. figure:: /auto_examples/images/thumb/sphx_glr_plot_comparing_uncertainties_for_regularization_thumb.png
- :alt: Comparing confidence intervals for regularization results
-
- :ref:`sphx_glr_auto_examples_plot_comparing_uncertainties_for_regularization.py`
-
-.. raw:: html
-
-
-
-
-.. toctree::
- :hidden:
-
- /auto_examples/plot_comparing_uncertainties_for_regularization
-
-.. raw:: html
-
-
-
-.. only:: html
-
- .. figure:: /auto_examples/images/thumb/sphx_glr_plot_analyzing_pake_pattern_thumb.png
- :alt: Analyzing the Pake pattern of a dipolar signal
-
- :ref:`sphx_glr_auto_examples_plot_analyzing_pake_pattern.py`
-
-.. raw:: html
-
-
-
-
-.. toctree::
- :hidden:
-
- /auto_examples/plot_analyzing_pake_pattern
-
-.. raw:: html
-
-
-
-.. only:: html
-
- .. figure:: /auto_examples/images/thumb/sphx_glr_plot_selecting_an_optimal_model_thumb.png
- :alt: Selecting an optimal parametric model for fitting a dipolar signal
-
- :ref:`sphx_glr_auto_examples_plot_selecting_an_optimal_model.py`
-
-.. raw:: html
-
-
-
-
-.. toctree::
- :hidden:
-
- /auto_examples/plot_selecting_an_optimal_model
-
-.. raw:: html
-
-
-
-.. only:: html
-
- .. figure:: /auto_examples/images/thumb/sphx_glr_plot_extracting_gauss_constraints_thumb.png
- :alt: Extracting Gaussian constraints from a parameter-free distribution fit
-
- :ref:`sphx_glr_auto_examples_plot_extracting_gauss_constraints.py`
-
-.. raw:: html
-
-
-
-
-.. toctree::
- :hidden:
-
- /auto_examples/plot_extracting_gauss_constraints
-
-.. raw:: html
-
-
-
-.. only:: html
-
- .. figure:: /auto_examples/images/thumb/sphx_glr_plot_emulating_deeranalysis_workflow_thumb.png
- :alt: Emulating the DeerAnalysis workflow
-
- :ref:`sphx_glr_auto_examples_plot_emulating_deeranalysis_workflow.py`
-
-.. raw:: html
-
-
-
-
-.. toctree::
- :hidden:
-
- /auto_examples/plot_emulating_deeranalysis_workflow
-
-.. raw:: html
-
-
-
-.. only:: html
-
- .. figure:: /auto_examples/images/thumb/sphx_glr_plot_fitting_custom_kernel_with_snlls_thumb.png
- :alt: Fitting a custom kernel model with a parameter-free distribution
-
- :ref:`sphx_glr_auto_examples_plot_fitting_custom_kernel_with_snlls.py`
-
-.. raw:: html
-
-
-
-
-.. toctree::
- :hidden:
-
- /auto_examples/plot_fitting_custom_kernel_with_snlls
-
-.. raw:: html
-
-
-
-.. only:: html
-
- .. figure:: /auto_examples/images/thumb/sphx_glr_plot_param_uncertainty_propagation_thumb.png
- :alt: Uncertainty propagation from parameter fits using covariance-based uncertainty quantificaion
-
- :ref:`sphx_glr_auto_examples_plot_param_uncertainty_propagation.py`
-
-.. raw:: html
-
-
-
-
-.. toctree::
- :hidden:
-
- /auto_examples/plot_param_uncertainty_propagation
-
-.. raw:: html
-
-
-
-.. only:: html
-
- .. figure:: /auto_examples/images/thumb/sphx_glr_plot_multigauss_fitting_4pdeer_thumb.png
- :alt: Multi-Gauss fit of a 4-pulse DEER signal
-
- :ref:`sphx_glr_auto_examples_plot_multigauss_fitting_4pdeer.py`
-
-.. raw:: html
-
-
-
-
-.. toctree::
- :hidden:
-
- /auto_examples/plot_multigauss_fitting_4pdeer
-
-.. raw:: html
-
-
-
-.. only:: html
-
- .. figure:: /auto_examples/images/thumb/sphx_glr_plot_globalfits_local_and_global_parameters_thumb.png
- :alt: Global model fits with global, local and fixed parameters
-
- :ref:`sphx_glr_auto_examples_plot_globalfits_local_and_global_parameters.py`
-
-.. raw:: html
-
-
-
-
-.. toctree::
- :hidden:
-
- /auto_examples/plot_globalfits_local_and_global_parameters
-
-.. raw:: html
-
-
-
-.. only:: html
-
- .. figure:: /auto_examples/images/thumb/sphx_glr_plot_bootstrapped_parameter_distributions_thumb.png
- :alt: Bootstrapped distributions of fit parameters
-
- :ref:`sphx_glr_auto_examples_plot_bootstrapped_parameter_distributions.py`
-
-.. raw:: html
-
-
-
-
-.. toctree::
- :hidden:
-
- /auto_examples/plot_bootstrapped_parameter_distributions
-
-.. raw:: html
-
-
-
-.. only:: html
-
- .. figure:: /auto_examples/images/thumb/sphx_glr_plot_pseudotitration_parameter_free_thumb.png
- :alt: Analyzing pseudo-titration (dose-respononse) curves with parameter-free distributions
-
- :ref:`sphx_glr_auto_examples_plot_pseudotitration_parameter_free.py`
-
-.. raw:: html
-
-
-
-
-.. toctree::
- :hidden:
-
- /auto_examples/plot_pseudotitration_parameter_free
-.. raw:: html
-
-
-
-
-
-.. only :: html
-
- .. container:: sphx-glr-footer
- :class: sphx-glr-footer-gallery
-
-
- .. container:: sphx-glr-download sphx-glr-download-python
-
- :download:`Download all examples in Python source code: auto_examples_python.zip `
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-jupyter
-
- :download:`Download all examples in Jupyter notebooks: auto_examples_jupyter.zip `
-
-
-.. only:: html
-
- .. rst-class:: sphx-glr-signature
-
- `Gallery generated by Sphinx-Gallery `_
diff --git a/docsrc/source/auto_examples/plot_analyzing_pake_pattern.py b/docsrc/source/auto_examples/plot_analyzing_pake_pattern.py
deleted file mode 100644
index 893fba997..000000000
--- a/docsrc/source/auto_examples/plot_analyzing_pake_pattern.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# %% [markdown]
-"""
-Analyzing the Pake pattern of a dipolar signal
-============================================================================
-
-A very basic example for displaying the Pake pattern of a given dipolar signal.
-"""
-# %%
-import numpy as np
-import matplotlib.pyplot as plt
-from deerlab import *
-
-# %% [markdown]
-# Generate a dipolar signal
-# -------------------------
-# Let's start by simulating a dipolar signal with some background and noise.
-
-# %%
-# Prepare components
-t = np.linspace(0,5,400)
-r = np.linspace(2,5,100)
-P = dd_gauss2(r,[3.5, 0.3, 0.2, 4, 0.2, 0.8])
-B = bg_exp(t,0.2)
-lam = 0.3
-K = dipolarkernel(t,r,lam,B)
-np.random.seed(0)
-V = K@P + whitegaussnoise(t,0.005)
-
-# Plot
-plt.plot(t,V,'k.')
-plt.tight_layout()
-plt.grid()
-plt.xlabel('Time [$\\mu s$]')
-plt.ylabel('V(t)')
-
-# %% [markdown]
-# Prepare the signal
-# ------------------
-# Since experimental dipolar signals contain the background, this must be fitted
-# removed prior to Fourier transform.
-#
-# First we proceed to fit the background function using some time-domain parametric
-# model. In this example we will use an exponential function (``bg_exp``).
-# Using the ``fitparamodel`` function we obtain the fitted background as well as
-# the fitted modulation depth.
-
-# %%
-
-tstart = 3 # Time to start fitting background, in us
-mask = t>tstart
-# Model for the background component (1-lambda)*B
-def Bmodel(par):
- lam,kappa = par
- B = (1 - lam)*bg_exp(t[mask],kappa)
- return B
-
-# Fit the background function
-fit = fitsignal(V,t,r,'P',bg_exp,ex_4pdeer,uqanalysis=False)
-Bfit = fit.B
-lam = fit.exparam
-kappa = fit.bgparam
-
-# %% [markdown]
-# Now we can use these fitted variables to isolate the dipolar evolution function
-# from the primary data. Removal of the background via division leads to a noise
-# increase at later times and thus to an approximation ``Vcorr`` of the real dipolar
-# evolution function.
-
-# %%
-
-# "Correct" for the background and modulation depth
-Vcorr = (V/Bfit - (1 - lam))/lam
-
-plt.plot(t,Vcorr,'k.')
-plt.tight_layout()
-plt.grid(alpha=0.3)
-plt.xlabel('Time [$\\mu s$]')
-plt.ylabel('V(t)')
-
-# %% [markdown]
-# Computing the Pake pattern
-# ---------------------------
-#
-# Now that the signal has the appropiate structure for Fourier transform it,
-# we can call the ``fftspec`` function to obtained the Pake pattern.
-
-# %%
-
-# Compute spectrum
-nu,pake = fftspec(Vcorr,t,apodization=False)
-
- # %% [markdown]
-# In order to avoid truncation ripples in the Fourier spectrum and at the same
-# time to compensate for the increase of noise, we recommend the use of apodization
-# using the appropiate option in ``fftspec``.
-
-# %%
-# Compute spectrum with apodization
-nuapo,pakeapo = fftspec(Vcorr,t,apodization=False,mode='real')
-
-# Plot results
-plt.plot(nu,pake,'k',nuapo,pakeapo,'b',linewidth=1.5)
-plt.tight_layout()
-plt.grid(alpha=0.3)
-plt.xlim([-10, 10])
-plt.xlabel('Frequency [MHz]')
-plt.ylabel('Intensity [a.u.]')
-plt.legend(['Raw','Apodized'])
-
-# %% [markdown]
-# We do not need to worry about the zero-filling since ``fftspec`` takes care
-# of setting it to twice the amount of points in the signal, to preserve all information.
-# Adding more points will artificially increase the resolution of the Pake pattern.
-# The improvement will only be visual as no further information can be gained
-# from additional zero-filling.
-
diff --git a/docsrc/source/auto_examples/plot_analyzing_pake_pattern.py.md5 b/docsrc/source/auto_examples/plot_analyzing_pake_pattern.py.md5
deleted file mode 100644
index dcb284d0b..000000000
--- a/docsrc/source/auto_examples/plot_analyzing_pake_pattern.py.md5
+++ /dev/null
@@ -1 +0,0 @@
-8b416e275b05352c23983e3dcf22b0bd
\ No newline at end of file
diff --git a/docsrc/source/auto_examples/plot_analyzing_pake_pattern.rst b/docsrc/source/auto_examples/plot_analyzing_pake_pattern.rst
deleted file mode 100644
index 0770c701b..000000000
--- a/docsrc/source/auto_examples/plot_analyzing_pake_pattern.rst
+++ /dev/null
@@ -1,244 +0,0 @@
-.. only:: html
-
- .. note::
- :class: sphx-glr-download-link-note
-
- Click :ref:`here ` to download the full example code
- .. rst-class:: sphx-glr-example-title
-
- .. _sphx_glr_auto_examples_plot_analyzing_pake_pattern.py:
-
-
-Analyzing the Pake pattern of a dipolar signal
-============================================================================
-
-A very basic example for displaying the Pake pattern of a given dipolar signal.
-
-
-.. code-block:: python
-
- import numpy as np
- import matplotlib.pyplot as plt
- from deerlab import *
-
-
-
-
-
-
-
-
-Generate a dipolar signal
--------------------------
-Let's start by simulating a dipolar signal with some background and noise.
-
-Prepare components
-
-
-.. code-block:: python
-
- t = np.linspace(0,5,400)
- r = np.linspace(2,5,100)
- P = dd_gauss2(r,[3.5, 0.3, 0.2, 4, 0.2, 0.8])
- B = bg_exp(t,0.2)
- lam = 0.3
- K = dipolarkernel(t,r,lam,B)
- np.random.seed(0)
- V = K@P + whitegaussnoise(t,0.005)
-
- # Plot
- plt.plot(t,V,'k.')
- plt.tight_layout()
- plt.grid()
- plt.xlabel('Time [$\\mu s$]')
- plt.ylabel('V(t)')
-
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_analyzing_pake_pattern_001.png
- :alt: plot analyzing pake pattern
- :class: sphx-glr-single-img
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
-
- Text(42.597222222222214, 0.5, 'V(t)')
-
-
-
-Prepare the signal
-------------------
-Since experimental dipolar signals contain the background, this must be fitted
-removed prior to Fourier transform.
-
-First we proceed to fit the background function using some time-domain parametric
-model. In this example we will use an exponential function (``bg_exp``).
-Using the ``fitparamodel`` function we obtain the fitted background as well as
-the fitted modulation depth.
-
-
-.. code-block:: python
-
-
- tstart = 3 # Time to start fitting background, in us
- mask = t>tstart
- # Model for the background component (1-lambda)*B
- def Bmodel(par):
- lam,kappa = par
- B = (1 - lam)*bg_exp(t[mask],kappa)
- return B
-
- # Fit the background function
- fit = fitsignal(V,t,r,'P',bg_exp,ex_4pdeer,uqanalysis=False)
- Bfit = fit.B
- lam = fit.exparam
- kappa = fit.bgparam
-
-
-
-
-
-
-
-
-Now we can use these fitted variables to isolate the dipolar evolution function
-from the primary data. Removal of the background via division leads to a noise
-increase at later times and thus to an approximation ``Vcorr`` of the real dipolar
-evolution function.
-
-
-.. code-block:: python
-
-
- # "Correct" for the background and modulation depth
- Vcorr = (V/Bfit - (1 - lam))/lam
-
- plt.plot(t,Vcorr,'k.')
- plt.tight_layout()
- plt.grid(alpha=0.3)
- plt.xlabel('Time [$\\mu s$]')
- plt.ylabel('V(t)')
-
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_analyzing_pake_pattern_002.png
- :alt: plot analyzing pake pattern
- :class: sphx-glr-single-img
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
-
- Text(30.972222222222214, 0.5, 'V(t)')
-
-
-
-Computing the Pake pattern
----------------------------
-
-Now that the signal has the appropiate structure for Fourier transform it,
-we can call the ``fftspec`` function to obtained the Pake pattern.
-
-
-.. code-block:: python
-
-
- # Compute spectrum
- nu,pake = fftspec(Vcorr,t,apodization=False)
-
- # %% [markdown]
- # In order to avoid truncation ripples in the Fourier spectrum and at the same
- # time to compensate for the increase of noise, we recommend the use of apodization
- # using the appropiate option in ``fftspec``.
-
-
-
-
-
-
-
-
-Compute spectrum with apodization
-
-
-.. code-block:: python
-
- nuapo,pakeapo = fftspec(Vcorr,t,apodization=False,mode='real')
-
- # Plot results
- plt.plot(nu,pake,'k',nuapo,pakeapo,'b',linewidth=1.5)
- plt.tight_layout()
- plt.grid(alpha=0.3)
- plt.xlim([-10, 10])
- plt.xlabel('Frequency [MHz]')
- plt.ylabel('Intensity [a.u.]')
- plt.legend(['Raw','Apodized'])
-
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_analyzing_pake_pattern_003.png
- :alt: plot analyzing pake pattern
- :class: sphx-glr-single-img
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
-
-
-
-
-
-We do not need to worry about the zero-filling since ``fftspec`` takes care
-of setting it to twice the amount of points in the signal, to preserve all information.
-Adding more points will artificially increase the resolution of the Pake pattern.
-The improvement will only be visual as no further information can be gained
-from additional zero-filling.
-
-
-.. rst-class:: sphx-glr-timing
-
- **Total running time of the script:** ( 0 minutes 1.026 seconds)
-
-
-.. _sphx_glr_download_auto_examples_plot_analyzing_pake_pattern.py:
-
-
-.. only :: html
-
- .. container:: sphx-glr-footer
- :class: sphx-glr-footer-example
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-python
-
- :download:`Download Python source code: plot_analyzing_pake_pattern.py `
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-jupyter
-
- :download:`Download Jupyter notebook: plot_analyzing_pake_pattern.ipynb `
-
-
-.. only:: html
-
- .. rst-class:: sphx-glr-signature
-
- `Gallery generated by Sphinx-Gallery `_
diff --git a/docsrc/source/auto_examples/plot_analyzing_pake_pattern_codeobj.pickle b/docsrc/source/auto_examples/plot_analyzing_pake_pattern_codeobj.pickle
deleted file mode 100644
index 6deeb4933..000000000
Binary files a/docsrc/source/auto_examples/plot_analyzing_pake_pattern_codeobj.pickle and /dev/null differ
diff --git a/docsrc/source/auto_examples/plot_bootstrapped_parameter_distributions.py b/docsrc/source/auto_examples/plot_bootstrapped_parameter_distributions.py
deleted file mode 100644
index cdc4450c1..000000000
--- a/docsrc/source/auto_examples/plot_bootstrapped_parameter_distributions.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# %% [markdown]
-"""
-Bootstrapped distributions of fit parameters
-============================================
-
-This example shows how to generate probability density functions of
-values for fit parameters using bootstrapping, showcased for 5pDEER.
-"""
-
-import numpy as np
-import matplotlib.pyplot as plt
-from deerlab import *
-
-# %% [markdown]
-# Generate data
-# -------------
-
-t = np.linspace(-0.1,6.5,100) # time axis, us
-r = np.linspace(1.5,6,100) # distance axis, ns
-param0 = [3, 0.3, 0.2, 3.5, 0.3, 0.65, 3.8, 0.2, 0.15] # parameters for three-Gaussian model
-P = dd_gauss3(r,param0) # model distance distribution
-B = lambda t,lam: bg_hom3d(t,300,lam) # background decay
-exparam = [0.6, 0.3, 0.1, 3.2] # parameters for 5pDEER experiment
-pathinfo = ex_5pdeer(exparam) # pathways information
-
-np.random.seed(0)
-K = dipolarkernel(t,r,pathinfo,B)
-Vexp = K@P + whitegaussnoise(t,0.01)
-
-# %% [markdown]
-# Analysis
-# --------
-#
-
-def fitroutine(V):
-
- # Set boundaries for the fit parameters (see DL_fitting_5pdeer.m)
- ex_lb = [ 0, 0, 0, max(t)/2-1] # lower bounds
- ex_ub = [10, 10, 10, max(t)/2+1] # upper bounds
- ex_par0 = [0.5, 0.5, 0.5, max(t)/2 ] # start values
- ub = [[],[],ex_ub]
- lb = [[],[],ex_lb]
- par0 = [[],[],ex_par0]
- # When running the fit, since we are only interested in the parameters we'll ignore
- # the rest (otherwise the ``Bfit``,``Pfit``,etc. could be bootstrapped as well)
- # We need the Vfit to pass it to bootan as well, so we'll request that one too.
- fit = fitsignal(V,t,r,'P',bg_hom3d,ex_5pdeer,par0,lb,ub,uqanalysis=False)
- Vfit = fit.V
- exparam = fit.exparam
- exparam[0:3] /=sum(exparam[0:3])
- bgparam = fit.bgparam
-
- return exparam,bgparam,Vfit
-
-
-# Run the fit once as usual, to check that the model fits the data
-exparfit,bgparfit,Vfit = fitroutine(Vexp)
-
-# Bootstrapping with 100 samples
-bootuq = bootan(fitroutine,Vexp,Vfit,100)
-
-# Extract the uncertainty quantification for the parameters
-exparam_uq = bootuq[0]
-bgparam_uq = bootuq[1]
-
-# Extract distributions for the experiment parameters
-Lam0_values,Lam0_pdf = exparam_uq.pardist(0)
-lam1_values,lam1_pdf = exparam_uq.pardist(1)
-lam2_values,lam2_pdf = exparam_uq.pardist(2)
-T02_values,T02_pdf = exparam_uq.pardist(3)
-
-# Extract distributions for the background parameters
-conc_values,conc_pdf = bgparam_uq.pardist(0)
-
-# %% [markdown]
-# Plot
-# --------
-
-plt.figure(figsize=(15,11))
-
-plt.subplot(321)
-plt.fill_between(Lam0_values,Lam0_pdf,color='b',alpha=0.4)
-plt.vlines(exparfit[0],0,max(Lam0_pdf),colors='k',linestyles='dashed',linewidth=2)
-plt.vlines(exparam[0],0,max(Lam0_pdf),colors='r',linestyles='dashed',linewidth=2)
-plt.xlabel('$\Lambda_0$')
-plt.ylabel('PDF')
-plt.legend(['Bootstrapped','Fit','Truth'])
-
-plt.subplot(322)
-plt.fill_between(lam1_values,lam1_pdf,color='b',alpha=0.4)
-plt.vlines(exparfit[1],0,max(lam1_pdf),colors='k',linestyles='dashed',linewidth=2)
-plt.vlines(exparam[1],0,max(lam1_pdf),colors='r',linestyles='dashed',linewidth=2)
-plt.xlabel('$\lambda_1$')
-plt.ylabel('PDF')
-
-plt.subplot(323)
-plt.fill_between(lam2_values,lam2_pdf,color='b',alpha=0.4)
-plt.vlines(exparfit[2],0,max(lam2_pdf),colors='k',linestyles='dashed',linewidth=2)
-plt.vlines(exparam[2],0,max(lam2_pdf),colors='r',linestyles='dashed',linewidth=2)
-plt.xlabel('$\lambda_2$')
-plt.ylabel('PDF')
-
-plt.subplot(324)
-plt.fill_between(T02_values,T02_pdf,color='b',alpha=0.4)
-plt.vlines(exparfit[3],0,max(T02_pdf),colors='k',linestyles='dashed',linewidth=2)
-plt.vlines(exparam[3],0,max(T02_pdf),colors='r',linestyles='dashed',linewidth=2)
-plt.xlabel('$T_{0,2}$ [$\mu s$]')
-plt.ylabel('PDF')
-
-plt.subplot(325)
-plt.fill_between(conc_values,conc_pdf,color='b',alpha=0.4)
-plt.vlines(bgparfit[0],0,max(conc_pdf),colors='k',linestyles='dashed',linewidth=2)
-plt.vlines(300,0,max(conc_pdf),colors='r',linestyles='dashed',linewidth=2)
-plt.xlabel('Spin conc. [$\mu M$]')
-plt.ylabel('PDF')
-
-
-
-# %%
diff --git a/docsrc/source/auto_examples/plot_bootstrapped_parameter_distributions.py.md5 b/docsrc/source/auto_examples/plot_bootstrapped_parameter_distributions.py.md5
deleted file mode 100644
index 4d69dd372..000000000
--- a/docsrc/source/auto_examples/plot_bootstrapped_parameter_distributions.py.md5
+++ /dev/null
@@ -1 +0,0 @@
-565c399747463651ca118e045963d6b5
\ No newline at end of file
diff --git a/docsrc/source/auto_examples/plot_bootstrapped_parameter_distributions.rst b/docsrc/source/auto_examples/plot_bootstrapped_parameter_distributions.rst
deleted file mode 100644
index abf979b78..000000000
--- a/docsrc/source/auto_examples/plot_bootstrapped_parameter_distributions.rst
+++ /dev/null
@@ -1,211 +0,0 @@
-.. only:: html
-
- .. note::
- :class: sphx-glr-download-link-note
-
- Click :ref:`here ` to download the full example code
- .. rst-class:: sphx-glr-example-title
-
- .. _sphx_glr_auto_examples_plot_bootstrapped_parameter_distributions.py:
-
-
-Bootstrapped distributions of fit parameters
-============================================
-
-This example shows how to generate probability density functions of
-values for fit parameters using bootstrapping, showcased for 5pDEER.
-
-
-.. code-block:: python
-
-
- import numpy as np
- import matplotlib.pyplot as plt
- from deerlab import *
-
-
-
-
-
-
-
-
-Generate data
--------------
-
-
-.. code-block:: python
-
-
- t = np.linspace(-0.1,6.5,100) # time axis, us
- r = np.linspace(1.5,6,100) # distance axis, ns
- param0 = [3, 0.3, 0.2, 3.5, 0.3, 0.65, 3.8, 0.2, 0.15] # parameters for three-Gaussian model
- P = dd_gauss3(r,param0) # model distance distribution
- B = lambda t,lam: bg_hom3d(t,300,lam) # background decay
- exparam = [0.6, 0.3, 0.1, 3.2] # parameters for 5pDEER experiment
- pathinfo = ex_5pdeer(exparam) # pathways information
-
- np.random.seed(0)
- K = dipolarkernel(t,r,pathinfo,B)
- Vexp = K@P + whitegaussnoise(t,0.01)
-
-
-
-
-
-
-
-
-Analysis
---------
-
-
-
-.. code-block:: python
-
-
- def fitroutine(V):
-
- # Set boundaries for the fit parameters (see DL_fitting_5pdeer.m)
- ex_lb = [ 0, 0, 0, max(t)/2-1] # lower bounds
- ex_ub = [10, 10, 10, max(t)/2+1] # upper bounds
- ex_par0 = [0.5, 0.5, 0.5, max(t)/2 ] # start values
- ub = [[],[],ex_ub]
- lb = [[],[],ex_lb]
- par0 = [[],[],ex_par0]
- # When running the fit, since we are only interested in the parameters we'll ignore
- # the rest (otherwise the ``Bfit``,``Pfit``,etc. could be bootstrapped as well)
- # We need the Vfit to pass it to bootan as well, so we'll request that one too.
- fit = fitsignal(V,t,r,'P',bg_hom3d,ex_5pdeer,par0,lb,ub,uqanalysis=False)
- Vfit = fit.V
- exparam = fit.exparam
- exparam[0:3] /=sum(exparam[0:3])
- bgparam = fit.bgparam
-
- return exparam,bgparam,Vfit
-
-
- # Run the fit once as usual, to check that the model fits the data
- exparfit,bgparfit,Vfit = fitroutine(Vexp)
-
- # Bootstrapping with 100 samples
- bootuq = bootan(fitroutine,Vexp,Vfit,100)
-
- # Extract the uncertainty quantification for the parameters
- exparam_uq = bootuq[0]
- bgparam_uq = bootuq[1]
-
- # Extract distributions for the experiment parameters
- Lam0_values,Lam0_pdf = exparam_uq.pardist(0)
- lam1_values,lam1_pdf = exparam_uq.pardist(1)
- lam2_values,lam2_pdf = exparam_uq.pardist(2)
- T02_values,T02_pdf = exparam_uq.pardist(3)
-
- # Extract distributions for the background parameters
- conc_values,conc_pdf = bgparam_uq.pardist(0)
-
-
-
-
-
-
-
-
-Plot
---------
-
-
-.. code-block:: python
-
-
- plt.figure(figsize=(15,11))
-
- plt.subplot(321)
- plt.fill_between(Lam0_values,Lam0_pdf,color='b',alpha=0.4)
- plt.vlines(exparfit[0],0,max(Lam0_pdf),colors='k',linestyles='dashed',linewidth=2)
- plt.vlines(exparam[0],0,max(Lam0_pdf),colors='r',linestyles='dashed',linewidth=2)
- plt.xlabel('$\Lambda_0$')
- plt.ylabel('PDF')
- plt.legend(['Bootstrapped','Fit','Truth'])
-
- plt.subplot(322)
- plt.fill_between(lam1_values,lam1_pdf,color='b',alpha=0.4)
- plt.vlines(exparfit[1],0,max(lam1_pdf),colors='k',linestyles='dashed',linewidth=2)
- plt.vlines(exparam[1],0,max(lam1_pdf),colors='r',linestyles='dashed',linewidth=2)
- plt.xlabel('$\lambda_1$')
- plt.ylabel('PDF')
-
- plt.subplot(323)
- plt.fill_between(lam2_values,lam2_pdf,color='b',alpha=0.4)
- plt.vlines(exparfit[2],0,max(lam2_pdf),colors='k',linestyles='dashed',linewidth=2)
- plt.vlines(exparam[2],0,max(lam2_pdf),colors='r',linestyles='dashed',linewidth=2)
- plt.xlabel('$\lambda_2$')
- plt.ylabel('PDF')
-
- plt.subplot(324)
- plt.fill_between(T02_values,T02_pdf,color='b',alpha=0.4)
- plt.vlines(exparfit[3],0,max(T02_pdf),colors='k',linestyles='dashed',linewidth=2)
- plt.vlines(exparam[3],0,max(T02_pdf),colors='r',linestyles='dashed',linewidth=2)
- plt.xlabel('$T_{0,2}$ [$\mu s$]')
- plt.ylabel('PDF')
-
- plt.subplot(325)
- plt.fill_between(conc_values,conc_pdf,color='b',alpha=0.4)
- plt.vlines(bgparfit[0],0,max(conc_pdf),colors='k',linestyles='dashed',linewidth=2)
- plt.vlines(300,0,max(conc_pdf),colors='r',linestyles='dashed',linewidth=2)
- plt.xlabel('Spin conc. [$\mu M$]')
- plt.ylabel('PDF')
-
-
-
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_bootstrapped_parameter_distributions_001.png
- :alt: plot bootstrapped parameter distributions
- :class: sphx-glr-single-img
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
-
- Text(0, 0.5, 'PDF')
-
-
-
-
-.. rst-class:: sphx-glr-timing
-
- **Total running time of the script:** ( 3 minutes 16.161 seconds)
-
-
-.. _sphx_glr_download_auto_examples_plot_bootstrapped_parameter_distributions.py:
-
-
-.. only :: html
-
- .. container:: sphx-glr-footer
- :class: sphx-glr-footer-example
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-python
-
- :download:`Download Python source code: plot_bootstrapped_parameter_distributions.py `
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-jupyter
-
- :download:`Download Jupyter notebook: plot_bootstrapped_parameter_distributions.ipynb `
-
-
-.. only:: html
-
- .. rst-class:: sphx-glr-signature
-
- `Gallery generated by Sphinx-Gallery `_
diff --git a/docsrc/source/auto_examples/plot_bootstrapped_parameter_distributions_codeobj.pickle b/docsrc/source/auto_examples/plot_bootstrapped_parameter_distributions_codeobj.pickle
deleted file mode 100644
index 51c4b898e..000000000
Binary files a/docsrc/source/auto_examples/plot_bootstrapped_parameter_distributions_codeobj.pickle and /dev/null differ
diff --git a/docsrc/source/auto_examples/plot_comparing_uncertainties_for_regularization.py b/docsrc/source/auto_examples/plot_comparing_uncertainties_for_regularization.py
deleted file mode 100644
index c6867d092..000000000
--- a/docsrc/source/auto_examples/plot_comparing_uncertainties_for_regularization.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# %% [markdown]
-"""
-Comparing confidence intervals for regularization results
-=========================================================
-
-A simpe example of uncertainty estimation for Tikhonov regularization
-results. The example will cover the use of confidence intervals
-obtained from curvature matrices and boostrap analysis.
-"""
-
-import numpy as np
-import matplotlib.pyplot as plt
-from deerlab import *
-
-# %% [markdown]
-# Simulate the data
-# ------------------
-#
-# Let's start by generating some data.
-
-
-# Prepare signal components
-t = np.linspace(-0.4,3.5,200)
-
-# Use a distance-axis with less points to make analysis faster
-r = np.linspace(2,5,200)
-
-P = dd_gauss2(r,[3, 0.3, 0.6, 3.5, 0.4, 0.4])
-B = bg_strexp(t,[0.04,1])
-lam = 0.32
-
-# Generate the dipolar kernel
-K = dipolarkernel(t,r,lam,B)
-# Simulate signal
-V = K@P + whitegaussnoise(t,0.01)
-
-# %% [markdown]
-# For the sake of simplicity, in this examples we will assume that we know the
-# background exactly. Our first step is to generate the proper dipolar kernel.
-#
-# Covariance-based confidence intervals
-# -------------------------------------
-#
-# We now have all the elements required to fit our distance distribution via
-# regularization. We will use the AIC to select the regularization parameter in
-# the Tikhonov regularization.
-
-# Fit data via regularization
-fit = fitregmodel(V,K,r,'tikhonov','aic')
-Pfit = fit.P
-Puq = fit.uncertainty
-# Obtain time-domain fit
-Vfit = K@Pfit
-
-plt.plot(r,P,'k',r,Pfit,'r',linewidth=1)
-Pci95 = Puq.ci(95)
-Pci50 = Puq.ci(50)
-plt.fill_between(r,Pci50[:,0],Pci50[:,1],color='r',linestyle='None',alpha=0.45)
-plt.fill_between(r,Pci95[:,0],Pci95[:,1],color='r',linestyle='None',alpha=0.25)
-plt.grid()
-plt.xlabel('r [nm]')
-plt.ylabel('P(r) [nm$^{-1}$]')
-plt.title('Curvature Matrix CI')
-plt.legend(['Truth','Fit','50%-CI','95%-CI'])
-
-# %% [markdown]
-# Bootstrapped confidence intervals
-# ---------------------------------
-#
-# Now we are interested in the bootstrap confidence intervals. For this, we
-# need to define a boot function e.g. ``mybootfcn()`` which takes a signal as
-# output and returns the outputs of interest (``Pfit`` in our example).
-
-
-def mybootfcn(V):
- fit = fitregmodel(V,K,r,'tikhonov','aic')
- return fit.P
-
-# Launch bootstrapping
-Nsamples = 50
-booci = bootan(mybootfcn,V,Vfit,Nsamples)
-Pci95 = booci.ci(95)
-Pci50 = booci.ci(50)
-
-# %% [markdown]
-# By plotting the results, one can see that the bootstrapped confidence intervals
-# are narrower in comparison to the ones obtained via the curvature
-# matrices. This is due to the inherent accurate nature of bootstrapping.
-
-plt.plot(r,P,'k',r,Pfit,'b',linewidth=1)
-plt.fill_between(r,Pci50[:,0],Pci50[:,1],color='b',linestyle='None',alpha=0.45)
-plt.fill_between(r,Pci95[:,0],Pci95[:,1],color='b',linestyle='None',alpha=0.25)
-plt.grid(alpha=0.3)
-plt.xlabel('r [nm]')
-plt.ylabel('P(r) [nm$^{-1}$]')
-plt.title('Bootstrapped CI')
-plt.legend(['Truth','Fit','50%-CI','95%-CI'])
-
-
-# %%
diff --git a/docsrc/source/auto_examples/plot_comparing_uncertainties_for_regularization.py.md5 b/docsrc/source/auto_examples/plot_comparing_uncertainties_for_regularization.py.md5
deleted file mode 100644
index 2ea4297c6..000000000
--- a/docsrc/source/auto_examples/plot_comparing_uncertainties_for_regularization.py.md5
+++ /dev/null
@@ -1 +0,0 @@
-3f049d2c7196ce63ce100013a08457e0
\ No newline at end of file
diff --git a/docsrc/source/auto_examples/plot_comparing_uncertainties_for_regularization.rst b/docsrc/source/auto_examples/plot_comparing_uncertainties_for_regularization.rst
deleted file mode 100644
index 822d44829..000000000
--- a/docsrc/source/auto_examples/plot_comparing_uncertainties_for_regularization.rst
+++ /dev/null
@@ -1,214 +0,0 @@
-.. only:: html
-
- .. note::
- :class: sphx-glr-download-link-note
-
- Click :ref:`here ` to download the full example code
- .. rst-class:: sphx-glr-example-title
-
- .. _sphx_glr_auto_examples_plot_comparing_uncertainties_for_regularization.py:
-
-
-Comparing confidence intervals for regularization results
-=========================================================
-
-A simpe example of uncertainty estimation for Tikhonov regularization
-results. The example will cover the use of confidence intervals
-obtained from curvature matrices and boostrap analysis.
-
-
-.. code-block:: python
-
-
- import numpy as np
- import matplotlib.pyplot as plt
- from deerlab import *
-
-
-
-
-
-
-
-
-Simulate the data
-------------------
-
-Let's start by generating some data.
-
-
-.. code-block:: python
-
-
-
- # Prepare signal components
- t = np.linspace(-0.4,3.5,200)
-
- # Use a distance-axis with less points to make analysis faster
- r = np.linspace(2,5,200)
-
- P = dd_gauss2(r,[3, 0.3, 0.6, 3.5, 0.4, 0.4])
- B = bg_strexp(t,[0.04,1])
- lam = 0.32
-
- # Generate the dipolar kernel
- K = dipolarkernel(t,r,lam,B)
- # Simulate signal
- V = K@P + whitegaussnoise(t,0.01)
-
-
-
-
-
-
-
-
-For the sake of simplicity, in this examples we will assume that we know the
-background exactly. Our first step is to generate the proper dipolar kernel.
-
-Covariance-based confidence intervals
--------------------------------------
-
-We now have all the elements required to fit our distance distribution via
-regularization. We will use the AIC to select the regularization parameter in
-the Tikhonov regularization.
-
-
-.. code-block:: python
-
-
- # Fit data via regularization
- fit = fitregmodel(V,K,r,'tikhonov','aic')
- Pfit = fit.P
- Puq = fit.uncertainty
- # Obtain time-domain fit
- Vfit = K@Pfit
-
- plt.plot(r,P,'k',r,Pfit,'r',linewidth=1)
- Pci95 = Puq.ci(95)
- Pci50 = Puq.ci(50)
- plt.fill_between(r,Pci50[:,0],Pci50[:,1],color='r',linestyle='None',alpha=0.45)
- plt.fill_between(r,Pci95[:,0],Pci95[:,1],color='r',linestyle='None',alpha=0.25)
- plt.grid()
- plt.xlabel('r [nm]')
- plt.ylabel('P(r) [nm$^{-1}$]')
- plt.title('Curvature Matrix CI')
- plt.legend(['Truth','Fit','50%-CI','95%-CI'])
-
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_comparing_uncertainties_for_regularization_001.png
- :alt: Curvature Matrix CI
- :class: sphx-glr-single-img
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
-
-
-
-
-
-Bootstrapped confidence intervals
----------------------------------
-
-Now we are interested in the bootstrap confidence intervals. For this, we
-need to define a boot function e.g. ``mybootfcn()`` which takes a signal as
-output and returns the outputs of interest (``Pfit`` in our example).
-
-
-.. code-block:: python
-
-
-
- def mybootfcn(V):
- fit = fitregmodel(V,K,r,'tikhonov','aic')
- return fit.P
-
- # Launch bootstrapping
- Nsamples = 50
- booci = bootan(mybootfcn,V,Vfit,Nsamples)
- Pci95 = booci.ci(95)
- Pci50 = booci.ci(50)
-
-
-
-
-
-
-
-
-By plotting the results, one can see that the bootstrapped confidence intervals
-are narrower in comparison to the ones obtained via the curvature
-matrices. This is due to the inherent accurate nature of bootstrapping.
-
-
-.. code-block:: python
-
-
- plt.plot(r,P,'k',r,Pfit,'b',linewidth=1)
- plt.fill_between(r,Pci50[:,0],Pci50[:,1],color='b',linestyle='None',alpha=0.45)
- plt.fill_between(r,Pci95[:,0],Pci95[:,1],color='b',linestyle='None',alpha=0.25)
- plt.grid(alpha=0.3)
- plt.xlabel('r [nm]')
- plt.ylabel('P(r) [nm$^{-1}$]')
- plt.title('Bootstrapped CI')
- plt.legend(['Truth','Fit','50%-CI','95%-CI'])
-
-
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_comparing_uncertainties_for_regularization_002.png
- :alt: Bootstrapped CI
- :class: sphx-glr-single-img
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
-
-
-
-
-
-
-.. rst-class:: sphx-glr-timing
-
- **Total running time of the script:** ( 0 minutes 10.482 seconds)
-
-
-.. _sphx_glr_download_auto_examples_plot_comparing_uncertainties_for_regularization.py:
-
-
-.. only :: html
-
- .. container:: sphx-glr-footer
- :class: sphx-glr-footer-example
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-python
-
- :download:`Download Python source code: plot_comparing_uncertainties_for_regularization.py `
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-jupyter
-
- :download:`Download Jupyter notebook: plot_comparing_uncertainties_for_regularization.ipynb `
-
-
-.. only:: html
-
- .. rst-class:: sphx-glr-signature
-
- `Gallery generated by Sphinx-Gallery `_
diff --git a/docsrc/source/auto_examples/plot_comparing_uncertainties_for_regularization_codeobj.pickle b/docsrc/source/auto_examples/plot_comparing_uncertainties_for_regularization_codeobj.pickle
deleted file mode 100644
index d83288c16..000000000
Binary files a/docsrc/source/auto_examples/plot_comparing_uncertainties_for_regularization_codeobj.pickle and /dev/null differ
diff --git a/docsrc/source/auto_examples/plot_emulating_deeranalysis_workflow.py b/docsrc/source/auto_examples/plot_emulating_deeranalysis_workflow.py
deleted file mode 100644
index c2f07a2ec..000000000
--- a/docsrc/source/auto_examples/plot_emulating_deeranalysis_workflow.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# %% [markdown]
-"""
-Emulating the DeerAnalysis workflow
-===================================
-
-This example shows how to reproduce the type of workflow implemented in
-DeerAnalysis, using DeerLab functions. This kind of analysis workflow is
-outdated and not recommended for routine or accurate data analysis.
-"""
-
-import numpy as np
-import matplotlib.pyplot as plt
-from deerlab import *
-
-# %% [markdown]
-# Generating a dataset
-#---------------------
-#
-# For this example we will simulate a simple 4pDEER signal
-
-# Parameters
-t = np.linspace(-0.1,3,250)
-rtrue = np.linspace(1,7,200)
-Ptrue = dd_gauss3(rtrue,[4.5, 0.6, 0.4, 3, 0.4, 0.3, 4, 0.7, 0.5])
-lam = 0.3
-conc = 180 #uM
-
-# Simulate an experimental signal with some a.u. and phase offset
-Bmodel = lambda t, lam: bg_hom3d(t,conc,lam)
-K = dipolarkernel(t,rtrue,lam,Bmodel)
-V = K@Ptrue*np.exp(1j*np.pi/16) # add a phase shift
-np.random.seed(1)
-rnoise = whitegaussnoise(t,0.01) # real-component noise
-np.random.seed(2)
-inoise = 1j*whitegaussnoise(t,0.01) # imaginary-component noise
-V = V + rnoise + inoise # complex-valued noisy signal
-V = V*3e6 # add an arbitrary amplitude scale
-
-plt.plot(t,V.real,'.',t,V.imag,'.'),
-plt.xlabel('t [$\mu s$]')
-plt.ylabel('V(t)')
-plt.grid(alpha=0.3)
-plt.legend(['real','imag'])
-
-# %% [markdown]
-# DeerAnalysis workflow
-# ---------------------
-#
-
-# Pre-processing
-V = correctphase(V)
-t = correctzerotime(V,t)
-V = V/max(V)
-
-# Distance axis estimation
-r = time2dist(t)
-
-# Background fit
-tstart = 1.0 # background fit start, in us
-mask = t>tstart
-def Bmodel(par):
- lam,kappa,d = par # unpack parameters
- B = (1-lam)*bg_strexp(t[mask],[kappa,d],lam)
- return B
-
-# lam k d
-par0 = [0.5, 0.5, 3]
-lb = [0.1, 0.1, 1]
-ub = [1, 5, 6]
-fit = fitparamodel(V[mask],Bmodel,par0,lb,ub,rescale=False)
-
-lamfit,kappa,d = fit.param
-Bfit = bg_strexp(t,[kappa,d],lamfit)
-
-# Background "correction" by division
-Vcorr = (V/Bfit - 1 + lamfit)/lamfit
-
-# Tikhonov regularization using the L-curve criterion
-K = dipolarkernel(t,r)
-fit = fitregmodel(Vcorr,K,r,'tikhonov','lr',)
-Pfit = fit.P
-
-# %% [markdown]
-# Plots
-# -----
-
-plt.subplot(311)
-plt.plot(t,V,'k.',t,(1-lamfit)*Bfit,'r',linewidth=1.5)
-plt.xlabel('t [\mus]')
-plt.ylabel('V(t)')
-plt.legend(['data','(1-\lambda)B$_{fit}$'])
-
-plt.subplot(312)
-plt.plot(t,Vcorr,'k.',t,K@Pfit,'r',linewidth=1.5)
-plt.xlabel('t [\mus]')
-plt.ylabel('V(t)')
-plt.legend(['corrected data','fit'])
-
-plt.subplot(313)
-plt.plot(rtrue,Ptrue,'k',r,Pfit,'r',linewidth=1.5)
-plt.xlabel('r [nm]')
-plt.ylabel('P [nm^{-1}]')
-plt.legend(['truth','fit'])
-
-
-# %%
diff --git a/docsrc/source/auto_examples/plot_emulating_deeranalysis_workflow.py.md5 b/docsrc/source/auto_examples/plot_emulating_deeranalysis_workflow.py.md5
deleted file mode 100644
index 8c2f219ef..000000000
--- a/docsrc/source/auto_examples/plot_emulating_deeranalysis_workflow.py.md5
+++ /dev/null
@@ -1 +0,0 @@
-49979b2d2aa08fba023e1f49d308b4d4
\ No newline at end of file
diff --git a/docsrc/source/auto_examples/plot_emulating_deeranalysis_workflow.rst b/docsrc/source/auto_examples/plot_emulating_deeranalysis_workflow.rst
deleted file mode 100644
index 8dfa97f4f..000000000
--- a/docsrc/source/auto_examples/plot_emulating_deeranalysis_workflow.rst
+++ /dev/null
@@ -1,219 +0,0 @@
-.. only:: html
-
- .. note::
- :class: sphx-glr-download-link-note
-
- Click :ref:`here ` to download the full example code
- .. rst-class:: sphx-glr-example-title
-
- .. _sphx_glr_auto_examples_plot_emulating_deeranalysis_workflow.py:
-
-
-Emulating the DeerAnalysis workflow
-===================================
-
-This example shows how to reproduce the type of workflow implemented in
-DeerAnalysis, using DeerLab functions. This kind of analysis workflow is
-outdated and not recommended for routine or accurate data analysis.
-
-
-.. code-block:: python
-
-
- import numpy as np
- import matplotlib.pyplot as plt
- from deerlab import *
-
-
-
-
-
-
-
-
-Generating a dataset
----------------------
-
- For this example we will simulate a simple 4pDEER signal
-
-
-.. code-block:: python
-
-
- # Parameters
- t = np.linspace(-0.1,3,250)
- rtrue = np.linspace(1,7,200)
- Ptrue = dd_gauss3(rtrue,[4.5, 0.6, 0.4, 3, 0.4, 0.3, 4, 0.7, 0.5])
- lam = 0.3
- conc = 180 #uM
-
- # Simulate an experimental signal with some a.u. and phase offset
- Bmodel = lambda t, lam: bg_hom3d(t,conc,lam)
- K = dipolarkernel(t,rtrue,lam,Bmodel)
- V = K@Ptrue*np.exp(1j*np.pi/16) # add a phase shift
- np.random.seed(1)
- rnoise = whitegaussnoise(t,0.01) # real-component noise
- np.random.seed(2)
- inoise = 1j*whitegaussnoise(t,0.01) # imaginary-component noise
- V = V + rnoise + inoise # complex-valued noisy signal
- V = V*3e6 # add an arbitrary amplitude scale
-
- plt.plot(t,V.real,'.',t,V.imag,'.'),
- plt.xlabel('t [$\mu s$]')
- plt.ylabel('V(t)')
- plt.grid(alpha=0.3)
- plt.legend(['real','imag'])
-
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_emulating_deeranalysis_workflow_001.png
- :alt: plot emulating deeranalysis workflow
- :class: sphx-glr-single-img
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
-
-
-
-
-
-DeerAnalysis workflow
----------------------
-
-
-
-.. code-block:: python
-
-
- # Pre-processing
- V = correctphase(V)
- t = correctzerotime(V,t)
- V = V/max(V)
-
- # Distance axis estimation
- r = time2dist(t)
-
- # Background fit
- tstart = 1.0 # background fit start, in us
- mask = t>tstart
- def Bmodel(par):
- lam,kappa,d = par # unpack parameters
- B = (1-lam)*bg_strexp(t[mask],[kappa,d],lam)
- return B
-
- # lam k d
- par0 = [0.5, 0.5, 3]
- lb = [0.1, 0.1, 1]
- ub = [1, 5, 6]
- fit = fitparamodel(V[mask],Bmodel,par0,lb,ub,rescale=False)
-
- lamfit,kappa,d = fit.param
- Bfit = bg_strexp(t,[kappa,d],lamfit)
-
- # Background "correction" by division
- Vcorr = (V/Bfit - 1 + lamfit)/lamfit
-
- # Tikhonov regularization using the L-curve criterion
- K = dipolarkernel(t,r)
- fit = fitregmodel(Vcorr,K,r,'tikhonov','lr',)
- Pfit = fit.P
-
-
-
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
- d:\lufa\projects\deerlab\deerlab\deerlab\fitparamodel.py:191: UserWarning: The fitted value of parameter #1, is at the lower bound of the range.
- warnings.warn('The fitted value of parameter #{}, is at the lower bound of the range.'.format(p))
-
-
-
-
-Plots
------
-
-
-.. code-block:: python
-
-
- plt.subplot(311)
- plt.plot(t,V,'k.',t,(1-lamfit)*Bfit,'r',linewidth=1.5)
- plt.xlabel('t [\mus]')
- plt.ylabel('V(t)')
- plt.legend(['data','(1-\lambda)B$_{fit}$'])
-
- plt.subplot(312)
- plt.plot(t,Vcorr,'k.',t,K@Pfit,'r',linewidth=1.5)
- plt.xlabel('t [\mus]')
- plt.ylabel('V(t)')
- plt.legend(['corrected data','fit'])
-
- plt.subplot(313)
- plt.plot(rtrue,Ptrue,'k',r,Pfit,'r',linewidth=1.5)
- plt.xlabel('r [nm]')
- plt.ylabel('P [nm^{-1}]')
- plt.legend(['truth','fit'])
-
-
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_emulating_deeranalysis_workflow_002.png
- :alt: plot emulating deeranalysis workflow
- :class: sphx-glr-single-img
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
-
-
-
-
-
-
-.. rst-class:: sphx-glr-timing
-
- **Total running time of the script:** ( 0 minutes 1.979 seconds)
-
-
-.. _sphx_glr_download_auto_examples_plot_emulating_deeranalysis_workflow.py:
-
-
-.. only :: html
-
- .. container:: sphx-glr-footer
- :class: sphx-glr-footer-example
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-python
-
- :download:`Download Python source code: plot_emulating_deeranalysis_workflow.py `
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-jupyter
-
- :download:`Download Jupyter notebook: plot_emulating_deeranalysis_workflow.ipynb `
-
-
-.. only:: html
-
- .. rst-class:: sphx-glr-signature
-
- `Gallery generated by Sphinx-Gallery `_
diff --git a/docsrc/source/auto_examples/plot_emulating_deeranalysis_workflow_codeobj.pickle b/docsrc/source/auto_examples/plot_emulating_deeranalysis_workflow_codeobj.pickle
deleted file mode 100644
index acf9d4c03..000000000
Binary files a/docsrc/source/auto_examples/plot_emulating_deeranalysis_workflow_codeobj.pickle and /dev/null differ
diff --git a/docsrc/source/auto_examples/plot_extracting_gauss_constraints.py b/docsrc/source/auto_examples/plot_extracting_gauss_constraints.py
deleted file mode 100644
index 8091cf9ee..000000000
--- a/docsrc/source/auto_examples/plot_extracting_gauss_constraints.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# %% [markdown]
-"""
-Extracting Gaussian constraints from a parameter-free distribution fit
-=======================================================================
-
-How to extract Gaussian constraints from a parameter-free fit.
-
-While parameter-free distance distributions are the most robust way to
-analyze dipolar signals, many structural biology modelling programs
-accept only estimators such as mean distances or Gaussian constraints.
-
-This example shows how to extract Gaussian constraints from a
-parameter-free fit of a dipolar signal and how to calculate the
-corresponding uncertainty.
-"""
-# %%
-
-import numpy as np
-import matplotlib.pyplot as plt
-from deerlab import *
-
-# %%
-
-# Generating a dataset
-# For this example we will simulate a simple 4pDEER signal
-
-# Parameters
-t = np.linspace(0,5,250)
-r = np.linspace(1,7,200)
-P = dd_gauss3(r,[4.5, 0.6, 0.4, 3, 0.4, 0.3, 4, 0.7, 0.5])
-lam = 0.3
-conc = 80; #uM
-
-# Simulate the signal
-Bmodel = lambda t,lam: bg_hom3d(t,conc,lam)
-K = dipolarkernel(t,r,lam,Bmodel)
-np.random.seed(0)
-V = K@P + whitegaussnoise(t,0.01)
-
-# %%
-
-# %% [markdown]
-# Fit the dipolar signal
-# ----------------------
-# First, we need to fit the parameter-free distance distribution using ``fitsignal()``
-# We are only interested right now on the fitted distribution and the
-# corresponding uncertainty quantification, so we will ignore the rest of
-# the outputs.
-# %%
-fit = fitsignal(V,t,r,'P',bg_exp,ex_4pdeer,display=True)
-Pfit = fit.P
-# %% [markdown]
-# Extract Gaussian constraints from the fit
-# -----------------------------------------
-# Next, we will fit a multi-Gauss distribution to the fitted parameter-free
-# distribution. We can do this by using the ``fitparamodel()`` function (in
-# this example, fitting a two-Gauss model).
-#
-# However, in order to get the correct uncertainty quantification, we need
-# to specify the covariance matrix of the fitted distribution.
-# ``fitparamodel()`` can then use that information to propagate the error in
-# ``Pfit`` to the Gauss constraints that we then fit.
-
-# %%
-# Extract the uncertainty quantification of the fitted distribution...
-Pfit_uq = fit.Puncert
-# ...specifically its covariance matrix
-Pfit_covmat = Pfit_uq.covmat
-
-# %% [markdown]
-#Fit a 2-Gauss model to the fitted parameter-free distribution:
-#
-# - ``parfit```: will contain the Gaussian constraints
-# - ``PGauss```: the corresponding distribution
-# - ``paruq```: the uncertainty quantification of our constraints
-
-
-# %%
-Pmodel = lambda p: dd_gauss2(r,p)
-# Get information on the model
-info = dd_gauss2()
-par0 = info['Start']
-lb = info['Lower']
-ub = info['Upper']
-fit = fitparamodel(Pfit,Pmodel,par0,lb,ub,covmatrix=Pfit_covmat)
-parfit = fit.param
-paruq = fit.uncertainty
-PGauss = dd_gauss2(r,parfit)
-
-# Extract the 95#-confidence intervals...
-par95 = paruq.ci(95)
-# ... and print the results of the constraints
-print('\nGaussian constraints:')
-info = dd_gauss2()
-for i in range(len(parfit)):
- print(' parfit[{}] = {:2.2f} ({:2.2f}, {:2.2f}) {}'.format(i,parfit[i],par95[i,0],par95[i,1],info['Parameters'][i]))
-
-# Now propagate the error of the constraints on the model
-lb = np.zeros_like(r) # Non-negativity constraint
-PGauss_uq = paruq.propagate(lambda par: dd_gauss2(r,par),lb)
-PGauss95 = PGauss_uq.ci(95)
-
-# %%
-
-# Plot the fitted constraints model on top of the parameter-free case
-plt.plot(r,Pfit,'r',linewidth=1.5)
-plt.fill_between(r,Pfit_uq.ci(95)[:,0], Pfit_uq.ci(95)[:,1],facecolor='r',linestyle='None',alpha=0.2)
-
-plt.plot(r,PGauss,'b',linewidth=1.5)
-plt.fill_between(r,PGauss95[:,0], PGauss95[:,1],facecolor='b',linestyle='None',alpha=0.2)
-
-plt.xlabel('Distance [nm]')
-plt.ylabel('P [nm$^{-1}$]')
-plt.tight_layout()
-plt.grid(alpha=0.3)
-plt.legend(['Fit','95%-CI','2G-constraints','95%-CI'])
-plt.show()
-
-
-# %%
diff --git a/docsrc/source/auto_examples/plot_extracting_gauss_constraints.py.md5 b/docsrc/source/auto_examples/plot_extracting_gauss_constraints.py.md5
deleted file mode 100644
index ce97ee26a..000000000
--- a/docsrc/source/auto_examples/plot_extracting_gauss_constraints.py.md5
+++ /dev/null
@@ -1 +0,0 @@
-e88bcadafbfd164e83bb9b9c59629ea9
\ No newline at end of file
diff --git a/docsrc/source/auto_examples/plot_extracting_gauss_constraints.rst b/docsrc/source/auto_examples/plot_extracting_gauss_constraints.rst
deleted file mode 100644
index 2b46b067f..000000000
--- a/docsrc/source/auto_examples/plot_extracting_gauss_constraints.rst
+++ /dev/null
@@ -1,249 +0,0 @@
-.. only:: html
-
- .. note::
- :class: sphx-glr-download-link-note
-
- Click :ref:`here ` to download the full example code
- .. rst-class:: sphx-glr-example-title
-
- .. _sphx_glr_auto_examples_plot_extracting_gauss_constraints.py:
-
-
-Extracting Gaussian constraints from a parameter-free distribution fit
-=======================================================================
-
-How to extract Gaussian constraints from a parameter-free fit.
-
-While parameter-free distance distributions are the most robust way to
-analyze dipolar signals, many structural biology modelling programs
-accept only estimators such as mean distances or Gaussian constraints.
-
-This example shows how to extract Gaussian constraints from a
-parameter-free fit of a dipolar signal and how to calculate the
-corresponding uncertainty.
-
-
-.. code-block:: python
-
-
- import numpy as np
- import matplotlib.pyplot as plt
- from deerlab import *
-
-
-
-
-
-
-
-
-
-.. code-block:: python
-
-
- # Generating a dataset
- # For this example we will simulate a simple 4pDEER signal
-
- # Parameters
- t = np.linspace(0,5,250)
- r = np.linspace(1,7,200)
- P = dd_gauss3(r,[4.5, 0.6, 0.4, 3, 0.4, 0.3, 4, 0.7, 0.5])
- lam = 0.3
- conc = 80; #uM
-
- # Simulate the signal
- Bmodel = lambda t,lam: bg_hom3d(t,conc,lam)
- K = dipolarkernel(t,r,lam,Bmodel)
- np.random.seed(0)
- V = K@P + whitegaussnoise(t,0.01)
-
-
-
-
-
-
-
-
-Fit the dipolar signal
-----------------------
-First, we need to fit the parameter-free distance distribution using ``fitsignal()``
-We are only interested right now on the fitted distribution and the
-corresponding uncertainty quantification, so we will ignore the rest of
-the outputs.
-%%
-
-
-.. code-block:: python
-
- fit = fitsignal(V,t,r,'P',bg_exp,ex_4pdeer,display=True)
- Pfit = fit.P
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_extracting_gauss_constraints_001.png
- :alt: plot extracting gauss constraints
- :class: sphx-glr-single-img
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
- ----------------------------------------------------------------------------
- Goodness of fit
- Vexp[0]: chi2 = 1.008065 RMSD = 0.009641
- ----------------------------------------------------------------------------
- Fitted parameters and 95%-confidence intervals
- parfit['bg'][0][0]: 0.0768264 (0.0223348, 0.1313180) Decay Rate (us-1)
- parfit['ex'][0][0]: 0.3129042 (0.2837829, 0.3420256) Modulation depth ()
- ----------------------------------------------------------------------------
-
-
-
-
-Extract Gaussian constraints from the fit
------------------------------------------
-Next, we will fit a multi-Gauss distribution to the fitted parameter-free
-distribution. We can do this by using the ``fitparamodel()`` function (in
-this example, fitting a two-Gauss model).
-
-However, in order to get the correct uncertainty quantification, we need
-to specify the covariance matrix of the fitted distribution.
-``fitparamodel()`` can then use that information to propagate the error in
-``Pfit`` to the Gauss constraints that we then fit.
-
-Extract the uncertainty quantification of the fitted distribution...
-
-
-.. code-block:: python
-
- Pfit_uq = fit.Puncert
- # ...specifically its covariance matrix
- Pfit_covmat = Pfit_uq.covmat
-
-
-
-
-
-
-
-
-Fit a 2-Gauss model to the fitted parameter-free distribution:
-
- - ``parfit```: will contain the Gaussian constraints
- - ``PGauss```: the corresponding distribution
- - ``paruq```: the uncertainty quantification of our constraints
-
-
-.. code-block:: python
-
- Pmodel = lambda p: dd_gauss2(r,p)
- # Get information on the model
- info = dd_gauss2()
- par0 = info['Start']
- lb = info['Lower']
- ub = info['Upper']
- fit = fitparamodel(Pfit,Pmodel,par0,lb,ub,covmatrix=Pfit_covmat)
- parfit = fit.param
- paruq = fit.uncertainty
- PGauss = dd_gauss2(r,parfit)
-
- # Extract the 95#-confidence intervals...
- par95 = paruq.ci(95)
- # ... and print the results of the constraints
- print('\nGaussian constraints:')
- info = dd_gauss2()
- for i in range(len(parfit)):
- print(' parfit[{}] = {:2.2f} ({:2.2f}, {:2.2f}) {}'.format(i,parfit[i],par95[i,0],par95[i,1],info['Parameters'][i]))
-
- # Now propagate the error of the constraints on the model
- lb = np.zeros_like(r) # Non-negativity constraint
- PGauss_uq = paruq.propagate(lambda par: dd_gauss2(r,par),lb)
- PGauss95 = PGauss_uq.ci(95)
-
-
-
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
-
- Gaussian constraints:
- parfit[0] = 3.02 (2.87, 3.17) Center of 1st Gaussian
- parfit[1] = 0.55 (0.29, 0.81) FWHM of 1st Gaussian
- parfit[2] = 0.25 (0.18, 0.33) Amplitude of 1st Gaussian
- parfit[3] = 4.29 (4.22, 4.36) Center of 2nd Gaussian
- parfit[4] = 0.94 (0.75, 1.13) FWHM of 2nd Gaussian
- parfit[5] = 0.67 (0.64, 0.70) Amplitude of 2nd Gaussian
-
-
-
-
-
-.. code-block:: python
-
-
- # Plot the fitted constraints model on top of the parameter-free case
- plt.plot(r,Pfit,'r',linewidth=1.5)
- plt.fill_between(r,Pfit_uq.ci(95)[:,0], Pfit_uq.ci(95)[:,1],facecolor='r',linestyle='None',alpha=0.2)
-
- plt.plot(r,PGauss,'b',linewidth=1.5)
- plt.fill_between(r,PGauss95[:,0], PGauss95[:,1],facecolor='b',linestyle='None',alpha=0.2)
-
- plt.xlabel('Distance [nm]')
- plt.ylabel('P [nm$^{-1}$]')
- plt.tight_layout()
- plt.grid(alpha=0.3)
- plt.legend(['Fit','95%-CI','2G-constraints','95%-CI'])
- plt.show()
-
-
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_extracting_gauss_constraints_002.png
- :alt: plot extracting gauss constraints
- :class: sphx-glr-single-img
-
-
-
-
-
-
-.. rst-class:: sphx-glr-timing
-
- **Total running time of the script:** ( 0 minutes 5.704 seconds)
-
-
-.. _sphx_glr_download_auto_examples_plot_extracting_gauss_constraints.py:
-
-
-.. only :: html
-
- .. container:: sphx-glr-footer
- :class: sphx-glr-footer-example
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-python
-
- :download:`Download Python source code: plot_extracting_gauss_constraints.py `
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-jupyter
-
- :download:`Download Jupyter notebook: plot_extracting_gauss_constraints.ipynb `
-
-
-.. only:: html
-
- .. rst-class:: sphx-glr-signature
-
- `Gallery generated by Sphinx-Gallery `_
diff --git a/docsrc/source/auto_examples/plot_extracting_gauss_constraints_codeobj.pickle b/docsrc/source/auto_examples/plot_extracting_gauss_constraints_codeobj.pickle
deleted file mode 100644
index 34f3b3003..000000000
Binary files a/docsrc/source/auto_examples/plot_extracting_gauss_constraints_codeobj.pickle and /dev/null differ
diff --git a/docsrc/source/auto_examples/plot_fitting_4pdeer.py b/docsrc/source/auto_examples/plot_fitting_4pdeer.py
deleted file mode 100644
index bbda4bc77..000000000
--- a/docsrc/source/auto_examples/plot_fitting_4pdeer.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# %% [markdown]
-"""
-Basic fitting of a 4-pulse DEER signal, non-parametric distribution
--------------------------------------------------------------------
-
-How to fit a simple 4-pulse DEER signal with a parameter-free distribution.
-"""
-# %%
-import numpy as np
-import matplotlib.pyplot as plt
-from deerlab import *
-
-# %% [markdown]
-#Generate data
-#--------------
-
-# %%
-t = np.linspace(-0.1,4,250) # time axis, us
-r = np.linspace(1.5,6,len(t)) # distance axis, ns
-param = [3, 0.3, 0.2, 3.5, 0.3, 0.65, 3.8, 0.2, 0.15] # parameters for three-Gaussian model
-P = dd_gauss3(r,param) # model distance distribution
-lam = 0.5 # modulation depth
-B = bg_hom3d(t,300,lam) # background decay
-K = dipolarkernel(t,r,lam,B)
-np.random.seed(0)
-Vexp = K@P + whitegaussnoise(t,0.01)
-
-
-# %% [markdown]
-# Run fit
-#---------
-
-# %%
-fit = fitsignal(Vexp,t,r,'P',bg_hom3d,ex_4pdeer,display=True)
-plt.show()
-
-# %%
diff --git a/docsrc/source/auto_examples/plot_fitting_4pdeer.py.md5 b/docsrc/source/auto_examples/plot_fitting_4pdeer.py.md5
deleted file mode 100644
index 7599bf876..000000000
--- a/docsrc/source/auto_examples/plot_fitting_4pdeer.py.md5
+++ /dev/null
@@ -1 +0,0 @@
-64a831d9b976a2ce581275833bf65f4b
\ No newline at end of file
diff --git a/docsrc/source/auto_examples/plot_fitting_4pdeer.rst b/docsrc/source/auto_examples/plot_fitting_4pdeer.rst
deleted file mode 100644
index 31175ea56..000000000
--- a/docsrc/source/auto_examples/plot_fitting_4pdeer.rst
+++ /dev/null
@@ -1,122 +0,0 @@
-.. only:: html
-
- .. note::
- :class: sphx-glr-download-link-note
-
- Click :ref:`here ` to download the full example code
- .. rst-class:: sphx-glr-example-title
-
- .. _sphx_glr_auto_examples_plot_fitting_4pdeer.py:
-
-
-Basic fitting of a 4-pulse DEER signal, non-parametric distribution
--------------------------------------------------------------------
-
-How to fit a simple 4-pulse DEER signal with a parameter-free distribution.
-
-
-.. code-block:: python
-
- import numpy as np
- import matplotlib.pyplot as plt
- from deerlab import *
-
-
-
-
-
-
-
-
-Generate data
---------------
-
-
-.. code-block:: python
-
- t = np.linspace(-0.1,4,250) # time axis, us
- r = np.linspace(1.5,6,len(t)) # distance axis, ns
- param = [3, 0.3, 0.2, 3.5, 0.3, 0.65, 3.8, 0.2, 0.15] # parameters for three-Gaussian model
- P = dd_gauss3(r,param) # model distance distribution
- lam = 0.5 # modulation depth
- B = bg_hom3d(t,300,lam) # background decay
- K = dipolarkernel(t,r,lam,B)
- np.random.seed(0)
- Vexp = K@P + whitegaussnoise(t,0.01)
-
-
-
-
-
-
-
-
-
-Run fit
----------
-
-
-.. code-block:: python
-
- fit = fitsignal(Vexp,t,r,'P',bg_hom3d,ex_4pdeer,display=True)
- plt.show()
-
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_fitting_4pdeer_001.png
- :alt: plot fitting 4pdeer
- :class: sphx-glr-single-img
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
- ----------------------------------------------------------------------------
- Goodness of fit
- Vexp[0]: chi2 = 1.008066 RMSD = 0.009758
- ----------------------------------------------------------------------------
- Fitted parameters and 95%-confidence intervals
- Vfit[0]:
- bgparam[0]: 295.8674273 (242.7909664, 348.9440294) Concentration of pumped spins (uM)
- exparam[0]: 0.5049229 (0.4828209, 0.5270251) Modulation depth ()
- ----------------------------------------------------------------------------
-
-
-
-
-
-.. rst-class:: sphx-glr-timing
-
- **Total running time of the script:** ( 0 minutes 5.652 seconds)
-
-
-.. _sphx_glr_download_auto_examples_plot_fitting_4pdeer.py:
-
-
-.. only :: html
-
- .. container:: sphx-glr-footer
- :class: sphx-glr-footer-example
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-python
-
- :download:`Download Python source code: plot_fitting_4pdeer.py `
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-jupyter
-
- :download:`Download Jupyter notebook: plot_fitting_4pdeer.ipynb `
-
-
-.. only:: html
-
- .. rst-class:: sphx-glr-signature
-
- `Gallery generated by Sphinx-Gallery `_
diff --git a/docsrc/source/auto_examples/plot_fitting_4pdeer_codeobj.pickle b/docsrc/source/auto_examples/plot_fitting_4pdeer_codeobj.pickle
deleted file mode 100644
index 8246e314c..000000000
Binary files a/docsrc/source/auto_examples/plot_fitting_4pdeer_codeobj.pickle and /dev/null differ
diff --git a/docsrc/source/auto_examples/plot_fitting_5pdeer.py b/docsrc/source/auto_examples/plot_fitting_5pdeer.py
deleted file mode 100644
index 397cd63d9..000000000
--- a/docsrc/source/auto_examples/plot_fitting_5pdeer.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# %% [markdown]
-"""
-Fitting a 5-pulse DEER signal with a parameter-free distribution
-==================================================================
-
-This example shows how to fit a 5-pulse DEER signal with a parameter-
-free distribution, a background, and all pathways parameters
-"""
-# %%
-import numpy as np
-import matplotlib.pyplot as plt
-from deerlab import *
-
-
-# %%
-# Generate data
-np.random.seed(1)
-t = np.linspace(-0.1,6.5,200) # time axis, us
-r = np.linspace(1.5,6,100) # distance axis, ns
-param0 = [3, 0.3, 0.2, 3.5, 0.3, 0.65, 3.8, 0.2, 0.15] # parameters for three-Gaussian model
-P = dd_gauss3(r,param0) # model distance distribution
-B = lambda t,lam: bg_hom3d(t,300,lam) # background decay
-exparam = [0.6, 0.3, 0.1, 3.2] # parameters for 5pDEER experiment
-pathinfo = ex_5pdeer(exparam) # pathways information
-
-K = dipolarkernel(t,r,pathinfo,B)
-Vexp = K@P + whitegaussnoise(t,0.005)
-
-# %% [markdown]
-# Now, 5pDEER data contain 3 additional parameters compared to 4pDEER (due
-# to the additional dipolar pathway present in the signal). However, the
-# refocusing time of the second dipolar pathway is very easy to constrain
-# and strongly helps stabilizing the fit.
-#
-# This pathway ususally refocuses at around ``t = max(t)/2``, and usually can
-# be even estimated from simple visual inspection of the signal.
-# Thus, we can strongly constraint this parameters while leaving the
-# pathway amplitudes pretty much unconstrained.
-#
-
-# %%
-ex_lb = [ 0, 0, 0, max(t)/2-1] # lower bounds
-ex_ub = [100, 100, 100, max(t)/2+1] # upper bounds
-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 = fitsignal(Vexp,t,r,'P',bg_hom3d,ex_5pdeer,par0,lb,ub,display=True)
-plt.show()
\ No newline at end of file
diff --git a/docsrc/source/auto_examples/plot_fitting_5pdeer.py.md5 b/docsrc/source/auto_examples/plot_fitting_5pdeer.py.md5
deleted file mode 100644
index c669793e4..000000000
--- a/docsrc/source/auto_examples/plot_fitting_5pdeer.py.md5
+++ /dev/null
@@ -1 +0,0 @@
-6f1159e746d996eef8ef5a27c8b0e83e
\ No newline at end of file
diff --git a/docsrc/source/auto_examples/plot_fitting_5pdeer.rst b/docsrc/source/auto_examples/plot_fitting_5pdeer.rst
deleted file mode 100644
index c572803e6..000000000
--- a/docsrc/source/auto_examples/plot_fitting_5pdeer.rst
+++ /dev/null
@@ -1,167 +0,0 @@
-.. only:: html
-
- .. note::
- :class: sphx-glr-download-link-note
-
- Click :ref:`here ` to download the full example code
- .. rst-class:: sphx-glr-example-title
-
- .. _sphx_glr_auto_examples_plot_fitting_5pdeer.py:
-
-
-Fitting a 5-pulse DEER signal with a parameter-free distribution
-==================================================================
-
-This example shows how to fit a 5-pulse DEER signal with a parameter-
-free distribution, a background, and all pathways parameters
-
-
-.. code-block:: python
-
- import numpy as np
- import matplotlib.pyplot as plt
- from deerlab import *
-
-
-
-
-
-
-
-
-
-Generate data
-
-
-.. code-block:: python
-
- np.random.seed(1)
- t = np.linspace(-0.1,6.5,200) # time axis, us
- r = np.linspace(1.5,6,100) # distance axis, ns
- param0 = [3, 0.3, 0.2, 3.5, 0.3, 0.65, 3.8, 0.2, 0.15] # parameters for three-Gaussian model
- P = dd_gauss3(r,param0) # model distance distribution
- B = lambda t,lam: bg_hom3d(t,300,lam) # background decay
- exparam = [0.6, 0.3, 0.1, 3.2] # parameters for 5pDEER experiment
- pathinfo = ex_5pdeer(exparam) # pathways information
-
- K = dipolarkernel(t,r,pathinfo,B)
- Vexp = K@P + whitegaussnoise(t,0.005)
-
-
-
-
-
-
-
-
-Now, 5pDEER data contain 3 additional parameters compared to 4pDEER (due
-to the additional dipolar pathway present in the signal). However, the
-refocusing time of the second dipolar pathway is very easy to constrain
-and strongly helps stabilizing the fit.
-
-This pathway ususally refocuses at around ``t = max(t)/2``, and usually can
-be even estimated from simple visual inspection of the signal.
-Thus, we can strongly constraint this parameters while leaving the
-pathway amplitudes pretty much unconstrained.
-
-
-
-.. code-block:: python
-
- ex_lb = [ 0, 0, 0, max(t)/2-1] # lower bounds
- ex_ub = [100, 100, 100, max(t)/2+1] # upper bounds
- ex_par0 = [0.5, 0.5, 0.5, max(t)/2 ] # start values
-
-
-
-
-
-
-
-
-In this case we only want to set the bounds for the experiment
-parameters, so we can leave the rest empty:
-
-
-
-.. code-block:: python
-
- ub = [[],[],ex_ub]
- lb = [[],[],ex_lb]
- par0 = [[],[],ex_par0]
-
-
-
-
-
-
-
-
-Run the fit with a 5-pulse DEER signal model
-
-
-.. code-block:: python
-
- fit = fitsignal(Vexp,t,r,'P',bg_hom3d,ex_5pdeer,par0,lb,ub,display=True)
- plt.show()
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_fitting_5pdeer_001.png
- :alt: plot fitting 5pdeer
- :class: sphx-glr-single-img
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
- ----------------------------------------------------------------------------
- Goodness of fit
- Vexp[0]: chi2 = 1.025641 RMSD = 0.004493
- ----------------------------------------------------------------------------
- Fitted parameters and 95%-confidence intervals
- Vfit[0]:
- bgparam[0]: 298.4495821 (290.9010012, 305.9983053) Concentration of pumped spins (uM)
- exparam[0]: 2.6414233 (2.6217640, 2.6610838) Amplitude of unmodulated components ()
- exparam[1]: 1.3196682 (1.2848191, 1.3545179) Amplitude of 1st modulated pathway ()
- exparam[2]: 0.4406813 (0.4220567, 0.4593060) Amplitude of 2nd modulated pathway ()
- exparam[3]: 3.2043365 (3.1985290, 3.2101455) Refocusing time of 2nd modulated pathway (us)
- ----------------------------------------------------------------------------
-
-
-
-
-
-.. rst-class:: sphx-glr-timing
-
- **Total running time of the script:** ( 0 minutes 9.454 seconds)
-
-
-.. _sphx_glr_download_auto_examples_plot_fitting_5pdeer.py:
-
-
-.. only :: html
-
- .. container:: sphx-glr-footer
- :class: sphx-glr-footer-example
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-python
-
- :download:`Download Python source code: plot_fitting_5pdeer.py `
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-jupyter
-
- :download:`Download Jupyter notebook: plot_fitting_5pdeer.ipynb `
-
-
-.. only:: html
-
- .. rst-class:: sphx-glr-signature
-
- `Gallery generated by Sphinx-Gallery `_
diff --git a/docsrc/source/auto_examples/plot_fitting_5pdeer_codeobj.pickle b/docsrc/source/auto_examples/plot_fitting_5pdeer_codeobj.pickle
deleted file mode 100644
index 851173ca4..000000000
Binary files a/docsrc/source/auto_examples/plot_fitting_5pdeer_codeobj.pickle and /dev/null differ
diff --git a/docsrc/source/auto_examples/plot_fitting_custom_kernel_with_snlls.py b/docsrc/source/auto_examples/plot_fitting_custom_kernel_with_snlls.py
deleted file mode 100644
index 9625f3670..000000000
--- a/docsrc/source/auto_examples/plot_fitting_custom_kernel_with_snlls.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# %% [markdown]
-"""
-Fitting a custom kernel model with a parameter-free distribution
-=================================================================
-
-How the use of SNLLS to fit a kernel model and a parameter-free
-distribution to a dipolar signal.
-"""
-import numpy as np
-import matplotlib.pyplot as plt
-from deerlab import *
-
-# %% [markdown]
-# Generating a dataset
-#-----------------------------------------------------------------------------
-# For this example we will simulate a simple 4pDEER signal
-
-t = np.linspace(-0.5,5,300)
-r = np.linspace(2,6,200)
-
-# Generate ground truth and input signal
-P = dd_gauss2(r,[3.5, 0.4, 0.4, 4.5, 0.7, 0.6])
-lam = 0.36
-c0 = 250 #uM
-B = bg_hom3d(t,c0,lam)
-K = dipolarkernel(t,r,lam,B)
-V = K@P + whitegaussnoise(t,0.01)
-
-# %% [markdown]
-# Fitting via SNLLS
-#------------------
-# Now in order to fit a non-linear dipolar kernel model ``Kmodel`` and a
-# linear parameter-free distance distribution ``Pfit`` simultaneously, we
-# can use the separable non-linear least squares ``SNLLS`` method.
-#
-# First we define the function that contains the model for the dipolar kernel we want to fit. It
-# is a non-linear functon that accepts the parameter array ``p`` and returns the
-# fitted dipolar kernel ``K``. The linear parameters, in this case ``P``, are
-# computed by solving a Tikhonov-regularized linear LSQ problem automatically in the ``snlls`` function.
-
-def Kmodel(p):
-
- # Unpack parameters
- lam,c0 = p
- # Get background
- B = bg_hom3d(t,c0,lam)
- # Generate 4pDEER kernel
- K = dipolarkernel(t,r,lam,B)
-
- return K
-
-# %% [markdown]
-# Next, there are two different parameter sets being fitted at the same time:
-# linear and non-linear parameters. Therefore, the lower/upper bounds for
-# the two sets need (or can) be specified.
-
-#--------------------------
-# Non-linear parameters:
-#--------------------------
-# lam c0
-#--------------------------
-par0 = [0.5, 50 ] # Start values
-lb = [ 0, 0.05] # lower bounds
-ub = [ 1, 1000] # upper bounds
-
-#--------------------------
-# Linear parameters:
-#--------------------------
-# Pfit
-#--------------------------
-lbl = np.zeros_like(r) # Non-negativity constraint of P
-ubl = [] # Unconstrained upper boundary
-
-# Run SNLLS optimization
-fit = snlls(V,Kmodel,par0,lb,ub,lbl,ubl)
-parfit = fit.nonlin
-Pfit = fit.lin
-paruq = fit.uncertainty
-
-# Get non-linear parameters uncertainty
-param95 = paruq.ci(95,'nonlin') # 95#-confidence interval
-
-# Get linear parameters (distribution) uncertainty
-Pci50 = paruq.ci(50,'lin') # 50#-confidence interval
-Pci95 = paruq.ci(95,'lin') # 95#-confidence interval
-
-# Print result
-print('lambda = {:.2f}({:.2f}-{:.2f})'.format(parfit[0],param95[0,0],param95[0,1]))
-print('c0 = {:.2f}({:.2f}-{:.2f})uM'.format(parfit[1],param95[1,0],param95[1,1]))
-
-# Get fitted model
-Kfit = Kmodel(parfit)
-Vfit = Kfit@Pfit
-
-# %% [markdown]
-# Plots
-#------
-
-plt.subplot(211)
-plt.plot(t,V,'k.',t,Vfit,'b')
-plt.grid(alpha=0.3)
-plt.xlabel('t [$\mu s$]')
-plt.ylabel('V(t)')
-plt.legend(['data','fit'])
-
-plt.subplot(212)
-plt.plot(r,P,'k',r,Pfit,'b')
-plt.fill_between(r,Pci50[:,0],Pci50[:,1],color='b',alpha=0.4,linestyle='None')
-plt.fill_between(r,Pci95[:,0],Pci95[:,1],color='b',alpha=0.2,linestyle='None')
-plt.grid(alpha=0.3)
-plt.xlabel('r [nm]')
-plt.ylabel('P(r) [nm$^{-1}$]')
-plt.legend(['truth','fit','50%-CI','95%-CI'])
-
-
-
-
-
-# %%
diff --git a/docsrc/source/auto_examples/plot_fitting_custom_kernel_with_snlls.py.md5 b/docsrc/source/auto_examples/plot_fitting_custom_kernel_with_snlls.py.md5
deleted file mode 100644
index 567295596..000000000
--- a/docsrc/source/auto_examples/plot_fitting_custom_kernel_with_snlls.py.md5
+++ /dev/null
@@ -1 +0,0 @@
-aab7da8528af59b0aea09b9932949086
\ No newline at end of file
diff --git a/docsrc/source/auto_examples/plot_fitting_custom_kernel_with_snlls.rst b/docsrc/source/auto_examples/plot_fitting_custom_kernel_with_snlls.rst
deleted file mode 100644
index 02e926dff..000000000
--- a/docsrc/source/auto_examples/plot_fitting_custom_kernel_with_snlls.rst
+++ /dev/null
@@ -1,230 +0,0 @@
-.. only:: html
-
- .. note::
- :class: sphx-glr-download-link-note
-
- Click :ref:`here ` to download the full example code
- .. rst-class:: sphx-glr-example-title
-
- .. _sphx_glr_auto_examples_plot_fitting_custom_kernel_with_snlls.py:
-
-
-Fitting a custom kernel model with a parameter-free distribution
-=================================================================
-
-How the use of SNLLS to fit a kernel model and a parameter-free
-distribution to a dipolar signal.
-
-
-.. code-block:: python
-
- import numpy as np
- import matplotlib.pyplot as plt
- from deerlab import *
-
-
-
-
-
-
-
-
-Generating a dataset
------------------------------------------------------------------------------
- For this example we will simulate a simple 4pDEER signal
-
-
-.. code-block:: python
-
-
- t = np.linspace(-0.5,5,300)
- r = np.linspace(2,6,200)
-
- # Generate ground truth and input signal
- P = dd_gauss2(r,[3.5, 0.4, 0.4, 4.5, 0.7, 0.6])
- lam = 0.36
- c0 = 250 #uM
- B = bg_hom3d(t,c0,lam)
- K = dipolarkernel(t,r,lam,B)
- V = K@P + whitegaussnoise(t,0.01)
-
-
-
-
-
-
-
-
-Fitting via SNLLS
-------------------
- Now in order to fit a non-linear dipolar kernel model ``Kmodel`` and a
- linear parameter-free distance distribution ``Pfit`` simultaneously, we
- can use the separable non-linear least squares ``SNLLS`` method.
-
- First we define the function that contains the model for the dipolar kernel we want to fit. It
- is a non-linear functon that accepts the parameter array ``p`` and returns the
- fitted dipolar kernel ``K``. The linear parameters, in this case ``P``, are
- computed by solving a Tikhonov-regularized linear LSQ problem automatically in the ``snlls`` function.
-
-
-.. code-block:: python
-
-
- def Kmodel(p):
-
- # Unpack parameters
- lam,c0 = p
- # Get background
- B = bg_hom3d(t,c0,lam)
- # Generate 4pDEER kernel
- K = dipolarkernel(t,r,lam,B)
-
- return K
-
-
-
-
-
-
-
-
-Next, there are two different parameter sets being fitted at the same time:
-linear and non-linear parameters. Therefore, the lower/upper bounds for
-the two sets need (or can) be specified.
-
-
-.. code-block:: python
-
-
- #--------------------------
- # Non-linear parameters:
- #--------------------------
- # lam c0
- #--------------------------
- par0 = [0.5, 50 ] # Start values
- lb = [ 0, 0.05] # lower bounds
- ub = [ 1, 1000] # upper bounds
-
- #--------------------------
- # Linear parameters:
- #--------------------------
- # Pfit
- #--------------------------
- lbl = np.zeros_like(r) # Non-negativity constraint of P
- ubl = [] # Unconstrained upper boundary
-
- # Run SNLLS optimization
- fit = snlls(V,Kmodel,par0,lb,ub,lbl,ubl)
- parfit = fit.nonlin
- Pfit = fit.lin
- paruq = fit.uncertainty
-
- # Get non-linear parameters uncertainty
- param95 = paruq.ci(95,'nonlin') # 95#-confidence interval
-
- # Get linear parameters (distribution) uncertainty
- Pci50 = paruq.ci(50,'lin') # 50#-confidence interval
- Pci95 = paruq.ci(95,'lin') # 95#-confidence interval
-
- # Print result
- print('lambda = {:.2f}({:.2f}-{:.2f})'.format(parfit[0],param95[0,0],param95[0,1]))
- print('c0 = {:.2f}({:.2f}-{:.2f})uM'.format(parfit[1],param95[1,0],param95[1,1]))
-
- # Get fitted model
- Kfit = Kmodel(parfit)
- Vfit = Kfit@Pfit
-
-
-
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
- lambda = 0.36(0.36-0.37)
- c0 = 254.67(243.34-266.00)uM
-
-
-
-
-Plots
-------
-
-
-.. code-block:: python
-
-
- plt.subplot(211)
- plt.plot(t,V,'k.',t,Vfit,'b')
- plt.grid(alpha=0.3)
- plt.xlabel('t [$\mu s$]')
- plt.ylabel('V(t)')
- plt.legend(['data','fit'])
-
- plt.subplot(212)
- plt.plot(r,P,'k',r,Pfit,'b')
- plt.fill_between(r,Pci50[:,0],Pci50[:,1],color='b',alpha=0.4,linestyle='None')
- plt.fill_between(r,Pci95[:,0],Pci95[:,1],color='b',alpha=0.2,linestyle='None')
- plt.grid(alpha=0.3)
- plt.xlabel('r [nm]')
- plt.ylabel('P(r) [nm$^{-1}$]')
- plt.legend(['truth','fit','50%-CI','95%-CI'])
-
-
-
-
-
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_fitting_custom_kernel_with_snlls_001.png
- :alt: plot fitting custom kernel with snlls
- :class: sphx-glr-single-img
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
-
-
-
-
-
-
-.. rst-class:: sphx-glr-timing
-
- **Total running time of the script:** ( 0 minutes 2.488 seconds)
-
-
-.. _sphx_glr_download_auto_examples_plot_fitting_custom_kernel_with_snlls.py:
-
-
-.. only :: html
-
- .. container:: sphx-glr-footer
- :class: sphx-glr-footer-example
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-python
-
- :download:`Download Python source code: plot_fitting_custom_kernel_with_snlls.py `
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-jupyter
-
- :download:`Download Jupyter notebook: plot_fitting_custom_kernel_with_snlls.ipynb `
-
-
-.. only:: html
-
- .. rst-class:: sphx-glr-signature
-
- `Gallery generated by Sphinx-Gallery `_
diff --git a/docsrc/source/auto_examples/plot_fitting_custom_kernel_with_snlls_codeobj.pickle b/docsrc/source/auto_examples/plot_fitting_custom_kernel_with_snlls_codeobj.pickle
deleted file mode 100644
index ed2314c62..000000000
Binary files a/docsrc/source/auto_examples/plot_fitting_custom_kernel_with_snlls_codeobj.pickle and /dev/null differ
diff --git a/docsrc/source/auto_examples/plot_fitting_mixed_model.py b/docsrc/source/auto_examples/plot_fitting_mixed_model.py
deleted file mode 100644
index d591a7356..000000000
--- a/docsrc/source/auto_examples/plot_fitting_mixed_model.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# %% [markdown]
-"""
-Fitting a mixed distance-distribution model
-===========================================
-
-Basic manipulation of parametric models and creating mixed models
-for fitting distance distributions.
-"""
-
-import numpy as np
-import matplotlib.pyplot as plt
-from deerlab import *
-
-# %% [markdown]
-# Simulate the data
-# -----------------
-#
-# Let's start by creating a simple dipolar evolution function (i.e. no background
-# and full modulation depth) corresponding to a simple 4-pulse DEER signal.
-
-#Axis definition
-t = np.linspace(-0.5,4,350)
-r = np.linspace(2,6,200)
-
-# Distribution parameters
-rmean = 4.5
-width = 0.3
-chain = 4.3
-pers = 10
-amp = 0.35
-
-# Generate distribution
-P = dd_gauss(r,[rmean, width])
-P = amp*P + (1 - amp)*dd_wormchain(r,[chain, pers])
-# Normalize distribution
-P = P/sum(P)/np.mean(np.diff(r))
-# Generate dipolar evolution function
-np.random.seed(0)
-K = dipolarkernel(t,r)
-V = K@P + whitegaussnoise(t,0.02)
-
-# %%
-# Generating a mixed parametric model
-# -----------------------------------
-#
-# 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
-# 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
-# parametric model. It's syntax is rather simple, we just have to pass the desired
-# parametric models as lambda functions.
-
-#Mix the models into new one
-gausswlc = mixmodels(dd_gauss,dd_wormchain)
-
-# %% [markdown]
-# Our new model ``gausswlc`` will now describe our sought linear combination of
-# both parametric models. We can check the state of the model by retrieving its
-# information
-
-#Get information on the mixed model
-info = gausswlc()
-
-# %% [markdown]
-# We can see that the ``mixmodels`` function has introduced an ampitude parameters
-# as the first parameter of the model. This parameters weights the contribution
-# of each individual parametric model. We see also that this is followed by the
-# parameters of the Gaussian model and finally with the parameters of the WLC
-# model.
-#
-# Our model is ready, and since it was generated from built-in models we do
-# not need to specify any parameters initial values or boundary constraints. These
-# can, however, by re-defined if the built-in defaults are not appropiate (see
-# other examples).
-#
-# Since we are dealing with a distance-domain model we require a dipolar kernel
-# to transform our model into time-domain. Remember that our signal in this example
-# is a dipolar evolution function, therefore we do not require anything else than
-# a very basic dipolar kernel.
-
-#Generate the dipolar evolution function kernel
-K = dipolarkernel(t,r)
-
-#Fit the model to the data
-Vmodel = lambda par: K@gausswlc(r,par)
-info = gausswlc()
-par0 = info['Start'] # built-in start values
-lb = info['Lower'] # built-in lower bounds
-ub = info['Upper'] # built-in upper bounds
-fit = fitparamodel(V,Vmodel,par0,lb,ub,MultiStart=10)
-fitpar = fit.param
-# %% [markdown]
-# From the fitted parameter set ``fitpar`` we can now generate our fitted distance
-# distribution and the corresponding time-domain fit.
-
-#Calculate the fitted model
-Pfit = gausswlc(r,fitpar)
-Vfit = Vmodel(fitpar)
-
-# %% [markdown]
-# Since we know both the ground truth for the distance distribution and the
-# dipolar signal, let's see how our fit turned out.
-
-#Plot results
-plt.subplot(2,1,1)
-plt.plot(t,V,'k.',t,Vfit,'r',linewidth=1.5)
-plt.xlabel('t [$\mu s$]')
-plt.ylabel('V(t)')
-plt.legend(['data','fit'])
-
-plt.subplot(2,1,2)
-plt.plot(r,P,'k',r,Pfit,'r',linewidth=1.5)
-plt.xlabel('r [nm]')
-plt.ylabel('P(r) [nm$^{-1}$]')
-plt.legend(['truth','fit'])
-
-
-# %%
diff --git a/docsrc/source/auto_examples/plot_fitting_mixed_model.py.md5 b/docsrc/source/auto_examples/plot_fitting_mixed_model.py.md5
deleted file mode 100644
index 3f22057f7..000000000
--- a/docsrc/source/auto_examples/plot_fitting_mixed_model.py.md5
+++ /dev/null
@@ -1 +0,0 @@
-7290a6ff788f51547c5bc165f90c463d
\ No newline at end of file
diff --git a/docsrc/source/auto_examples/plot_fitting_mixed_model.rst b/docsrc/source/auto_examples/plot_fitting_mixed_model.rst
deleted file mode 100644
index e3aa7eeda..000000000
--- a/docsrc/source/auto_examples/plot_fitting_mixed_model.rst
+++ /dev/null
@@ -1,242 +0,0 @@
-.. only:: html
-
- .. note::
- :class: sphx-glr-download-link-note
-
- Click :ref:`here ` to download the full example code
- .. rst-class:: sphx-glr-example-title
-
- .. _sphx_glr_auto_examples_plot_fitting_mixed_model.py:
-
-
-Fitting a mixed distance-distribution model
-===========================================
-
-Basic manipulation of parametric models and creating mixed models
-for fitting distance distributions.
-
-
-.. code-block:: python
-
-
- import numpy as np
- import matplotlib.pyplot as plt
- from deerlab import *
-
-
-
-
-
-
-
-
-Simulate the data
------------------
-
-Let's start by creating a simple dipolar evolution function (i.e. no background
-and full modulation depth) corresponding to a simple 4-pulse DEER signal.
-
-
-.. code-block:: python
-
-
- #Axis definition
- t = np.linspace(-0.5,4,350)
- r = np.linspace(2,6,200)
-
- # Distribution parameters
- rmean = 4.5
- width = 0.3
- chain = 4.3
- pers = 10
- amp = 0.35
-
- # Generate distribution
- P = dd_gauss(r,[rmean, width])
- P = amp*P + (1 - amp)*dd_wormchain(r,[chain, pers])
- # Normalize distribution
- P = P/sum(P)/np.mean(np.diff(r))
- # Generate dipolar evolution function
- np.random.seed(0)
- K = dipolarkernel(t,r)
- V = K@P + whitegaussnoise(t,0.02)
-
-
-
-
-
-
-
-
-Generating a mixed parametric model
------------------------------------
-
-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
-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
-parametric model. It's syntax is rather simple, we just have to pass the desired
-parametric models as lambda functions.
-
-
-.. code-block:: python
-
-
- #Mix the models into new one
- gausswlc = mixmodels(dd_gauss,dd_wormchain)
-
-
-
-
-
-
-
-
-Our new model ``gausswlc`` will now describe our sought linear combination of
-both parametric models. We can check the state of the model by retrieving its
-information
-
-
-.. code-block:: python
-
-
- #Get information on the mixed model
- info = gausswlc()
-
-
-
-
-
-
-
-
-We can see that the ``mixmodels`` function has introduced an ampitude parameters
-as the first parameter of the model. This parameters weights the contribution
-of each individual parametric model. We see also that this is followed by the
-parameters of the Gaussian model and finally with the parameters of the WLC
-model.
-
-Our model is ready, and since it was generated from built-in models we do
-not need to specify any parameters initial values or boundary constraints. These
-can, however, by re-defined if the built-in defaults are not appropiate (see
-other examples).
-
-Since we are dealing with a distance-domain model we require a dipolar kernel
-to transform our model into time-domain. Remember that our signal in this example
-is a dipolar evolution function, therefore we do not require anything else than
-a very basic dipolar kernel.
-
-
-.. code-block:: python
-
-
- #Generate the dipolar evolution function kernel
- K = dipolarkernel(t,r)
-
- #Fit the model to the data
- Vmodel = lambda par: K@gausswlc(r,par)
- info = gausswlc()
- par0 = info['Start'] # built-in start values
- lb = info['Lower'] # built-in lower bounds
- ub = info['Upper'] # built-in upper bounds
- fit = fitparamodel(V,Vmodel,par0,lb,ub,MultiStart=10)
- fitpar = fit.param
-
-
-
-
-
-
-
-From the fitted parameter set ``fitpar`` we can now generate our fitted distance
-distribution and the corresponding time-domain fit.
-
-
-.. code-block:: python
-
-
- #Calculate the fitted model
- Pfit = gausswlc(r,fitpar)
- Vfit = Vmodel(fitpar)
-
-
-
-
-
-
-
-
-Since we know both the ground truth for the distance distribution and the
-dipolar signal, let's see how our fit turned out.
-
-
-.. code-block:: python
-
-
- #Plot results
- plt.subplot(2,1,1)
- plt.plot(t,V,'k.',t,Vfit,'r',linewidth=1.5)
- plt.xlabel('t [$\mu s$]')
- plt.ylabel('V(t)')
- plt.legend(['data','fit'])
-
- plt.subplot(2,1,2)
- plt.plot(r,P,'k',r,Pfit,'r',linewidth=1.5)
- plt.xlabel('r [nm]')
- plt.ylabel('P(r) [nm$^{-1}$]')
- plt.legend(['truth','fit'])
-
-
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_fitting_mixed_model_001.png
- :alt: plot fitting mixed model
- :class: sphx-glr-single-img
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
-
-
-
-
-
-
-.. rst-class:: sphx-glr-timing
-
- **Total running time of the script:** ( 0 minutes 26.163 seconds)
-
-
-.. _sphx_glr_download_auto_examples_plot_fitting_mixed_model.py:
-
-
-.. only :: html
-
- .. container:: sphx-glr-footer
- :class: sphx-glr-footer-example
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-python
-
- :download:`Download Python source code: plot_fitting_mixed_model.py `
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-jupyter
-
- :download:`Download Jupyter notebook: plot_fitting_mixed_model.ipynb `
-
-
-.. only:: html
-
- .. rst-class:: sphx-glr-signature
-
- `Gallery generated by Sphinx-Gallery `_
diff --git a/docsrc/source/auto_examples/plot_fitting_mixed_model_codeobj.pickle b/docsrc/source/auto_examples/plot_fitting_mixed_model_codeobj.pickle
deleted file mode 100644
index 632519fbb..000000000
Binary files a/docsrc/source/auto_examples/plot_fitting_mixed_model_codeobj.pickle and /dev/null differ
diff --git a/docsrc/source/auto_examples/plot_globalfits_local_and_global_parameters.py b/docsrc/source/auto_examples/plot_globalfits_local_and_global_parameters.py
deleted file mode 100644
index 19d3eeb77..000000000
--- a/docsrc/source/auto_examples/plot_globalfits_local_and_global_parameters.py
+++ /dev/null
@@ -1,169 +0,0 @@
-# %% [markdown]
-"""
-Global model fits with global, local and fixed parameters
-=========================================================
-
-This example shows how to fit multiple signals to a global model, which
-may depend on some parameters which need to be globally fitted, some
-locally and some might be fixed and not fitted.
-
-"""
-
-import numpy as np
-import matplotlib.pyplot as plt
-from deerlab import *
-
-# %% [markdown]
-# Generate two datasets
-#-----------------------------------------------------------------------------
-# For this example we will simulate a system containing two states A and B
-# both havng a Gaussian distribution of known width but unknown mean
-# distance. For this system we have two measurements V1 amd V2 measured
-# under two different conditions leading to different fractions of states A
-# and B.
-
-r = np.linspace(2,6,300) # distance axis, in nm
-t1 = np.linspace(0,4,200) # time axis of first measurement, in us
-t2 = np.linspace(0,6,150) # time axis of first measurement, in us
-
-# Parameters
-rmeanA = 3.45 # mean distance state A, in nm
-rmeanB = 5.05 # mean distance state B, in nm
-fwhmA = 0.5 # FWHM state A, in nm
-fwhmB = 0.3 # FWHM state B, in nm
-
-fracA1 = 0.8 # Molar fraction of state A under conditions 1
-fracA2 = 0.2 # Molar fraction of state A under conditions 2
-# The molar fraction of state B is not required as it follows fracB = 1 - fracA
-
-# Generate the two distributions for conditions 1 & 2
-P1 = dd_gauss2(r,[rmeanA, fwhmA, fracA1, rmeanB, fwhmB, 1-fracA1])
-P2 = dd_gauss2(r,[rmeanA, fwhmA, fracA2, rmeanB, fwhmB, 1-fracA2])
-
-# Generate the corresponding dipolar kernels
-K1 = dipolarkernel(t1,r)
-K2 = dipolarkernel(t2,r)
-
-# ...and the two corresponding signals
-np.random.seed(0)
-V1 = K1@P1 + whitegaussnoise(t1,0.01)
-np.random.seed(1)
-V2 = K2@P2 + whitegaussnoise(t2,0.02)
-# (for the sake of simplicity no background and 100# modulation depth are assumed)
-
-# %% [markdown]
-# Global fit
-# ----------
-# Now when considering such systems is always important to (1) identify the
-# parameters which must be fitted and (2) identify which parameters are the
-# same for all signals (global) and which are specific for a individual
-# signal (local).
-#
-# In this examples we have the following parameters:
-# - fixed: ``fwhmA``, ``fwhmB`` (known paramters)
-# - global: ``rmeanA``, ``rmeanB`` (same for both signals)
-# - local: ``fracA1``, ``fracA2`` (different for both signals/conditions)
-#
-# The next step is to construct the model function which describes our
-# system. This function models the signals in our A-B system, and it is used to
-# simulate all signals passed to ``fitparamodel``. The function must
-# return (at least) a list of simulations of all the signals
-# passed to ``fitparamodel``.
-
-# Model definition
-def myABmodel(par):
-
- #Fixed parameters
- fwhmA = 0.5
- fwhmB = 0.3
- #Global parameters
- rmeanA = par[0]
- rmeanB = par[1]
- #Local parameters
- fracA1 = par[2]
- fracA2 = par[3]
-
- # Generate the signal-specific distribution
- Pfit1 = dd_gauss2(r,[rmeanA, fwhmA, fracA1, rmeanB, fwhmB, max(1-fracA1,0)])
- Pfit2 = dd_gauss2(r,[rmeanA, fwhmA, fracA2, rmeanB, fwhmB, max(1-fracA2,0)])
-
- # Generate signal #1
- V1fit = K1@Pfit1
- # Generate signal #2
- V2fit = K2@Pfit2
- # Return as a list
- Vfits = [V1fit,V2fit]
-
- return Vfits,Pfit1,Pfit2
-
-#-----------------------------------------
-# Fit parameters
-#-----------------------------------------
-# [rmeanA rmeanB fracA1 fracA2]
-#-----------------------------------------
-par0 = [2, 2, 0.5, 0.5]
-lower = [1, 1, 0, 0]
-upper = [20, 20, 1, 1]
-#-----------------------------------------
-
-# %% [markdown]
-# Note that our model function ``myABmodel`` returns multiple outputs.
-# This is advantegoud to later recover all fits directly, however, the fit
-# function does only allow one output, specifically, the list of simulated signals.
-# Therefore, we must create a lambda function which just takes the first ouput argument
-# of ``myABmodel``.
-
-model = lambda par: myABmodel(par)[0] # call myABmodel with par and take the first output
-
-# Collect data for global fit into cell arrays
-Vs = [V1,V2]
-
-# Fit the global parametric model to both signals
-fit = fitparamodel(Vs,model,par0,lower,upper,MultiStart=40)
-
-# The use of the option 'multistart' will help the solver to find the
-# global minimum and not to get stuck at local minima.
-
-# Get the fitted models
-Vfits,Pfit1,Pfit2 = myABmodel(fit.param)
-Vfit1 = Vfits[0]
-Vfit2 = Vfits[1]
-
-# %% [markdown]
-# Plot results
-# ------------
-plt.subplot(221)
-plt.plot(t1,V1,'k.',t1,Vfit1,'r')
-plt.grid(alpha=0.3)
-plt.xlabel('t [$\mu s$]')
-plt.ylabel('V(t)')
-plt.title('Conditions #1')
-
-plt.subplot(222)
-plt.plot(r,P1,'k',r,Pfit1,'r')
-plt.grid(alpha=0.3)
-plt.xlabel('r [nm]')
-plt.ylabel('P(r) [nm]^{-1}')
-plt.legend(['truth','fit'])
-
-plt.subplot(223)
-plt.plot(t2,V2,'k.',t2,Vfit2,'b')
-plt.grid(alpha=0.3)
-plt.xlabel('t [$\mu s$]')
-plt.ylabel('V(t)')
-plt.title('Conditions #2')
-
-plt.subplot(224)
-plt.plot(r,P2,'k',r,Pfit2,'b')
-plt.grid(alpha=0.3)
-plt.xlabel('r [nm]')
-plt.ylabel('P(r) [nm]$^{-1}$')
-plt.legend(['truth','fit'])
-
-plt.tight_layout()
-
-
-# %%
-
-
-# %%
diff --git a/docsrc/source/auto_examples/plot_globalfits_local_and_global_parameters.py.md5 b/docsrc/source/auto_examples/plot_globalfits_local_and_global_parameters.py.md5
deleted file mode 100644
index 7450bc275..000000000
--- a/docsrc/source/auto_examples/plot_globalfits_local_and_global_parameters.py.md5
+++ /dev/null
@@ -1 +0,0 @@
-8900272e4705e6eeaac37be87c9bddd6
\ No newline at end of file
diff --git a/docsrc/source/auto_examples/plot_globalfits_local_and_global_parameters.rst b/docsrc/source/auto_examples/plot_globalfits_local_and_global_parameters.rst
deleted file mode 100644
index 7676a560f..000000000
--- a/docsrc/source/auto_examples/plot_globalfits_local_and_global_parameters.rst
+++ /dev/null
@@ -1,260 +0,0 @@
-.. only:: html
-
- .. note::
- :class: sphx-glr-download-link-note
-
- Click :ref:`here ` to download the full example code
- .. rst-class:: sphx-glr-example-title
-
- .. _sphx_glr_auto_examples_plot_globalfits_local_and_global_parameters.py:
-
-
-Global model fits with global, local and fixed parameters
-=========================================================
-
-This example shows how to fit multiple signals to a global model, which
-may depend on some parameters which need to be globally fitted, some
-locally and some might be fixed and not fitted.
-
-
-
-.. code-block:: python
-
-
- import numpy as np
- import matplotlib.pyplot as plt
- from deerlab import *
-
-
-
-
-
-
-
-
-Generate two datasets
------------------------------------------------------------------------------
- For this example we will simulate a system containing two states A and B
- both havng a Gaussian distribution of known width but unknown mean
- distance. For this system we have two measurements V1 amd V2 measured
- under two different conditions leading to different fractions of states A
- and B.
-
-
-.. code-block:: python
-
-
- r = np.linspace(2,6,300) # distance axis, in nm
- t1 = np.linspace(0,4,200) # time axis of first measurement, in us
- t2 = np.linspace(0,6,150) # time axis of first measurement, in us
-
- # Parameters
- rmeanA = 3.45 # mean distance state A, in nm
- rmeanB = 5.05 # mean distance state B, in nm
- fwhmA = 0.5 # FWHM state A, in nm
- fwhmB = 0.3 # FWHM state B, in nm
-
- fracA1 = 0.8 # Molar fraction of state A under conditions 1
- fracA2 = 0.2 # Molar fraction of state A under conditions 2
- # The molar fraction of state B is not required as it follows fracB = 1 - fracA
-
- # Generate the two distributions for conditions 1 & 2
- P1 = dd_gauss2(r,[rmeanA, fwhmA, fracA1, rmeanB, fwhmB, 1-fracA1])
- P2 = dd_gauss2(r,[rmeanA, fwhmA, fracA2, rmeanB, fwhmB, 1-fracA2])
-
- # Generate the corresponding dipolar kernels
- K1 = dipolarkernel(t1,r)
- K2 = dipolarkernel(t2,r)
-
- # ...and the two corresponding signals
- np.random.seed(0)
- V1 = K1@P1 + whitegaussnoise(t1,0.01)
- np.random.seed(1)
- V2 = K2@P2 + whitegaussnoise(t2,0.02)
- # (for the sake of simplicity no background and 100# modulation depth are assumed)
-
-
-
-
-
-
-
-
-Global fit
-----------
-Now when considering such systems is always important to (1) identify the
-parameters which must be fitted and (2) identify which parameters are the
-same for all signals (global) and which are specific for a individual
-signal (local).
-
-In this examples we have the following parameters:
- - fixed: ``fwhmA``, ``fwhmB`` (known paramters)
- - global: ``rmeanA``, ``rmeanB`` (same for both signals)
- - local: ``fracA1``, ``fracA2`` (different for both signals/conditions)
-
-The next step is to construct the model function which describes our
-system. This function models the signals in our A-B system, and it is used to
-simulate all signals passed to ``fitparamodel``. The function must
-return (at least) a list of simulations of all the signals
-passed to ``fitparamodel``.
-
-
-.. code-block:: python
-
-
- # Model definition
- def myABmodel(par):
-
- #Fixed parameters
- fwhmA = 0.5
- fwhmB = 0.3
- #Global parameters
- rmeanA = par[0]
- rmeanB = par[1]
- #Local parameters
- fracA1 = par[2]
- fracA2 = par[3]
-
- # Generate the signal-specific distribution
- Pfit1 = dd_gauss2(r,[rmeanA, fwhmA, fracA1, rmeanB, fwhmB, max(1-fracA1,0)])
- Pfit2 = dd_gauss2(r,[rmeanA, fwhmA, fracA2, rmeanB, fwhmB, max(1-fracA2,0)])
-
- # Generate signal #1
- V1fit = K1@Pfit1
- # Generate signal #2
- V2fit = K2@Pfit2
- # Return as a list
- Vfits = [V1fit,V2fit]
-
- return Vfits,Pfit1,Pfit2
-
- #-----------------------------------------
- # Fit parameters
- #-----------------------------------------
- # [rmeanA rmeanB fracA1 fracA2]
- #-----------------------------------------
- par0 = [2, 2, 0.5, 0.5]
- lower = [1, 1, 0, 0]
- upper = [20, 20, 1, 1]
- #-----------------------------------------
-
-
-
-
-
-
-
-
-Note that our model function ``myABmodel`` returns multiple outputs.
-This is advantegoud to later recover all fits directly, however, the fit
-function does only allow one output, specifically, the list of simulated signals.
-Therefore, we must create a lambda function which just takes the first ouput argument
-of ``myABmodel``.
-
-
-.. code-block:: python
-
-
- model = lambda par: myABmodel(par)[0] # call myABmodel with par and take the first output
-
- # Collect data for global fit into cell arrays
- Vs = [V1,V2]
-
- # Fit the global parametric model to both signals
- fit = fitparamodel(Vs,model,par0,lower,upper,MultiStart=40)
-
- # The use of the option 'multistart' will help the solver to find the
- # global minimum and not to get stuck at local minima.
-
- # Get the fitted models
- Vfits,Pfit1,Pfit2 = myABmodel(fit.param)
- Vfit1 = Vfits[0]
- Vfit2 = Vfits[1]
-
-
-
-
-
-
-
-
-Plot results
-------------
-
-
-.. code-block:: python
-
- plt.subplot(221)
- plt.plot(t1,V1,'k.',t1,Vfit1,'r')
- plt.grid(alpha=0.3)
- plt.xlabel('t [$\mu s$]')
- plt.ylabel('V(t)')
- plt.title('Conditions #1')
-
- plt.subplot(222)
- plt.plot(r,P1,'k',r,Pfit1,'r')
- plt.grid(alpha=0.3)
- plt.xlabel('r [nm]')
- plt.ylabel('P(r) [nm]^{-1}')
- plt.legend(['truth','fit'])
-
- plt.subplot(223)
- plt.plot(t2,V2,'k.',t2,Vfit2,'b')
- plt.grid(alpha=0.3)
- plt.xlabel('t [$\mu s$]')
- plt.ylabel('V(t)')
- plt.title('Conditions #2')
-
- plt.subplot(224)
- plt.plot(r,P2,'k',r,Pfit2,'b')
- plt.grid(alpha=0.3)
- plt.xlabel('r [nm]')
- plt.ylabel('P(r) [nm]$^{-1}$')
- plt.legend(['truth','fit'])
-
- plt.tight_layout()
-
-
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_globalfits_local_and_global_parameters_001.png
- :alt: Conditions #1, Conditions #2
- :class: sphx-glr-single-img
-
-
-
-
-
-
-.. rst-class:: sphx-glr-timing
-
- **Total running time of the script:** ( 0 minutes 3.470 seconds)
-
-
-.. _sphx_glr_download_auto_examples_plot_globalfits_local_and_global_parameters.py:
-
-
-.. only :: html
-
- .. container:: sphx-glr-footer
- :class: sphx-glr-footer-example
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-python
-
- :download:`Download Python source code: plot_globalfits_local_and_global_parameters.py `
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-jupyter
-
- :download:`Download Jupyter notebook: plot_globalfits_local_and_global_parameters.ipynb `
-
-
-.. only:: html
-
- .. rst-class:: sphx-glr-signature
-
- `Gallery generated by Sphinx-Gallery `_
diff --git a/docsrc/source/auto_examples/plot_globalfits_local_and_global_parameters_codeobj.pickle b/docsrc/source/auto_examples/plot_globalfits_local_and_global_parameters_codeobj.pickle
deleted file mode 100644
index 75a5097f4..000000000
Binary files a/docsrc/source/auto_examples/plot_globalfits_local_and_global_parameters_codeobj.pickle and /dev/null differ
diff --git a/docsrc/source/auto_examples/plot_multigauss_fitting_4pdeer.py b/docsrc/source/auto_examples/plot_multigauss_fitting_4pdeer.py
deleted file mode 100644
index 012186653..000000000
--- a/docsrc/source/auto_examples/plot_multigauss_fitting_4pdeer.py
+++ /dev/null
@@ -1,141 +0,0 @@
-# %% [markdown]
-"""
-Multi-Gauss fit of a 4-pulse DEER signal
-========================================
-
-This example showcases how to fit a simple 4-pulse DEER signal with
-background using a multi-Gauss model, i.e automatically optimizing the
-number of Gaussians in the model.
-"""
-import numpy as np
-import matplotlib.pyplot as plt
-from deerlab import *
-
-
-# %% [markdown]
-# Model function for a 4pDEER dipolar kernel
-# ------------------------------------------
-# The first step for this analysis requires the definition of a parametric dipolar kernel
-# for the description of a 4-pulse DEER experiment.
-
-def K4pdeer(par,t,r):
-
- # Unpack parameters
- lam,conc = par
- # Simualte background
- B = bg_hom3d(t,conc,lam)
- # Generate dipolar kernel
- K = dipolarkernel(t,r,lam,B)
-
- return K
-
-# %% [markdown]
-# Generating a dataset
-# ---------------------
-
-t = np.linspace(-0.25,4,300) # time axis, us
-r = np.linspace(2.5,4.5,300) # distance axis, nm
-param0 = [3, 0.3, 0.2, 3.5, 0.3, 0.45, 3.9, 0.2, 0.20] # parameters for three-Gaussian model
-P = dd_gauss3(r,param0) # ground truth distance distribution
-lam = 0.3 # modulation depth
-conc = 250 # spin concentration, uM
-noiselvl = 0.005 # noise level
-
-# Generate 4pDEER dipolar signal with noise
-np.random.seed(0)
-V = K4pdeer([lam,conc],t,r)@P + whitegaussnoise(t,noiselvl)
-
-# %% [markdown]
-# Multi-Gauss fitting
-# -------------------
-
-# Parameter bounds:
-# lambda conc rmean fwhm
-lb = [1, 0.05] # distribution basis function lower bounds
-ub = [20, 5] # distribution basis function upper bounds
-lbK = [0, 0.05] # kernel parameters lower bounds
-ubK = [1, 1500] # kernel parameters upper bounds
-
-# Prepare the kernel model
-Kmodel = lambda par: K4pdeer(par,t,r)
-NGauss = 5 # maximum number of Gaussians
-
-# Fit the kernel parameters with an optimized multi-Gauss distribution
-fit = fitmultimodel(V,Kmodel,r,dd_gauss,NGauss,'aic',lb,ub,lbK,ubK)
-#Extract results
-Pfit = fit.P
-Kparfit = fit.Kparam
-Puq = fit.Puncert
-paramuq = fit.paramUncert
-metrics = fit.selfun
-Peval = fit.Pn
-
-# Get the time-domain fit
-K = Kmodel(Kparfit)
-Vfit = K@Pfit
-
-# Confidence intervals of the fitted distance distribution
-Pci95 = Puq.ci(95) # 95#-confidence interval
-Pci50 = Puq.ci(50) # 50#-confidence interval
-
-# %% [markdown]
-# Akaike weights
-#-----------------------------------------------------------------------------
-# When comparing different parametric models is always a good idea to look
-# at the Akaike weights for each model. They basically tell you the
-# probability of a model being the most optimal choice.
-
-# Compute the Akaike weights
-dAIC = metrics - min(metrics)
-Akaikeweights = 100*np.exp(-dAIC/2)/sum(np.exp(-dAIC/2))
-# %%
-# Plots
-
-plt.figure(figsize=(10,5))
-
-plt.subplot(3,2,1)
-plt.plot(t,V,'k.')
-plt.plot(t,Vfit,'b',linewidth=1.5)
-plt.plot(t,(1-Kparfit[0])*bg_hom3d(t,Kparfit[1],Kparfit[0]),'b--',linewidth=1.5)
-plt.tight_layout()
-plt.grid(alpha=0.3)
-plt.legend(['data','Vfit','Bfit'])
-plt.xlabel('t [$\mu s$]')
-plt.ylabel('V(t)')
-
-plt.subplot(322)
-plt.plot(r,P,'k',linewidth=1.5)
-plt.plot(r,Pfit,'b',linewidth=1.5)
-plt.fill_between(r,Pci50[:,0],Pci50[:,1],color='b',linestyle='None',alpha=0.45)
-plt.fill_between(r,Pci95[:,0],Pci95[:,1],color='b',linestyle='None',alpha=0.25)
-plt.tight_layout()
-plt.grid(alpha=0.3)
-plt.legend(['truth','optimal fit','95%-CI'])
-plt.xlabel('r [nm]')
-plt.ylabel('P(r)')
-
-plt.subplot(323)
-plt.bar(np.arange(NGauss)+1,metrics + abs(min(metrics)),facecolor='b',alpha=0.6)
-plt.tight_layout()
-plt.grid(alpha=0.3)
-plt.ylabel('$\Delta AIC$')
-plt.xlabel('Number of Gaussians')
-
-plt.subplot(325)
-plt.bar(np.arange(NGauss)+1,Akaikeweights,facecolor='b',alpha=0.6)
-plt.tight_layout()
-plt.grid(alpha=0.3)
-plt.ylabel('Akaike Weight [%]')
-plt.xlabel('Number of Gaussians')
-
-plt.subplot(3,2,(4,6))
-for i in range(len(Peval)):
- plt.plot(r,P + 2*i,'k',r,Peval[i] + 2*i,'b-',linewidth=1.5)
-plt.tight_layout()
-plt.grid(alpha=0.3)
-plt.xlabel('r [nm]')
-plt.ylabel('Number of Gaussians')
-plt.legend(['truth','fit'])
-
-
-# %%
diff --git a/docsrc/source/auto_examples/plot_multigauss_fitting_4pdeer.py.md5 b/docsrc/source/auto_examples/plot_multigauss_fitting_4pdeer.py.md5
deleted file mode 100644
index 0c3b0fda5..000000000
--- a/docsrc/source/auto_examples/plot_multigauss_fitting_4pdeer.py.md5
+++ /dev/null
@@ -1 +0,0 @@
-8d8ca70b236c34f4ac1af1b7968d8d49
\ No newline at end of file
diff --git a/docsrc/source/auto_examples/plot_multigauss_fitting_4pdeer.rst b/docsrc/source/auto_examples/plot_multigauss_fitting_4pdeer.rst
deleted file mode 100644
index 0f920e348..000000000
--- a/docsrc/source/auto_examples/plot_multigauss_fitting_4pdeer.rst
+++ /dev/null
@@ -1,253 +0,0 @@
-.. only:: html
-
- .. note::
- :class: sphx-glr-download-link-note
-
- Click :ref:`here ` to download the full example code
- .. rst-class:: sphx-glr-example-title
-
- .. _sphx_glr_auto_examples_plot_multigauss_fitting_4pdeer.py:
-
-
-Multi-Gauss fit of a 4-pulse DEER signal
-========================================
-
-This example showcases how to fit a simple 4-pulse DEER signal with
-background using a multi-Gauss model, i.e automatically optimizing the
-number of Gaussians in the model.
-
-
-.. code-block:: python
-
- import numpy as np
- import matplotlib.pyplot as plt
- from deerlab import *
-
-
-
-
-
-
-
-
-
-Model function for a 4pDEER dipolar kernel
-------------------------------------------
-The first step for this analysis requires the definition of a parametric dipolar kernel
-for the description of a 4-pulse DEER experiment.
-
-
-.. code-block:: python
-
-
- def K4pdeer(par,t,r):
-
- # Unpack parameters
- lam,conc = par
- # Simualte background
- B = bg_hom3d(t,conc,lam)
- # Generate dipolar kernel
- K = dipolarkernel(t,r,lam,B)
-
- return K
-
-
-
-
-
-
-
-
-Generating a dataset
----------------------
-
-
-.. code-block:: python
-
-
- t = np.linspace(-0.25,4,300) # time axis, us
- r = np.linspace(2.5,4.5,300) # distance axis, nm
- param0 = [3, 0.3, 0.2, 3.5, 0.3, 0.45, 3.9, 0.2, 0.20] # parameters for three-Gaussian model
- P = dd_gauss3(r,param0) # ground truth distance distribution
- lam = 0.3 # modulation depth
- conc = 250 # spin concentration, uM
- noiselvl = 0.005 # noise level
-
- # Generate 4pDEER dipolar signal with noise
- np.random.seed(0)
- V = K4pdeer([lam,conc],t,r)@P + whitegaussnoise(t,noiselvl)
-
-
-
-
-
-
-
-
-Multi-Gauss fitting
--------------------
-
-
-.. code-block:: python
-
-
- # Parameter bounds:
- # lambda conc rmean fwhm
- lb = [1, 0.05] # distribution basis function lower bounds
- ub = [20, 5] # distribution basis function upper bounds
- lbK = [0, 0.05] # kernel parameters lower bounds
- ubK = [1, 1500] # kernel parameters upper bounds
-
- # Prepare the kernel model
- Kmodel = lambda par: K4pdeer(par,t,r)
- NGauss = 5 # maximum number of Gaussians
-
- # Fit the kernel parameters with an optimized multi-Gauss distribution
- fit = fitmultimodel(V,Kmodel,r,dd_gauss,NGauss,'aic',lb,ub,lbK,ubK)
- #Extract results
- Pfit = fit.P
- Kparfit = fit.Kparam
- Puq = fit.Puncert
- paramuq = fit.paramUncert
- metrics = fit.selfun
- Peval = fit.Pn
-
- # Get the time-domain fit
- K = Kmodel(Kparfit)
- Vfit = K@Pfit
-
- # Confidence intervals of the fitted distance distribution
- Pci95 = Puq.ci(95) # 95#-confidence interval
- Pci50 = Puq.ci(50) # 50#-confidence interval
-
-
-
-
-
-
-
-
-Akaike weights
------------------------------------------------------------------------------
- When comparing different parametric models is always a good idea to look
- at the Akaike weights for each model. They basically tell you the
- probability of a model being the most optimal choice.
-
-
-.. code-block:: python
-
-
- # Compute the Akaike weights
- dAIC = metrics - min(metrics)
- Akaikeweights = 100*np.exp(-dAIC/2)/sum(np.exp(-dAIC/2))
-
-
-
-
-
-
-
-Plots
-
-
-.. code-block:: python
-
-
- plt.figure(figsize=(10,5))
-
- plt.subplot(3,2,1)
- plt.plot(t,V,'k.')
- plt.plot(t,Vfit,'b',linewidth=1.5)
- plt.plot(t,(1-Kparfit[0])*bg_hom3d(t,Kparfit[1],Kparfit[0]),'b--',linewidth=1.5)
- plt.tight_layout()
- plt.grid(alpha=0.3)
- plt.legend(['data','Vfit','Bfit'])
- plt.xlabel('t [$\mu s$]')
- plt.ylabel('V(t)')
-
- plt.subplot(322)
- plt.plot(r,P,'k',linewidth=1.5)
- plt.plot(r,Pfit,'b',linewidth=1.5)
- plt.fill_between(r,Pci50[:,0],Pci50[:,1],color='b',linestyle='None',alpha=0.45)
- plt.fill_between(r,Pci95[:,0],Pci95[:,1],color='b',linestyle='None',alpha=0.25)
- plt.tight_layout()
- plt.grid(alpha=0.3)
- plt.legend(['truth','optimal fit','95%-CI'])
- plt.xlabel('r [nm]')
- plt.ylabel('P(r)')
-
- plt.subplot(323)
- plt.bar(np.arange(NGauss)+1,metrics + abs(min(metrics)),facecolor='b',alpha=0.6)
- plt.tight_layout()
- plt.grid(alpha=0.3)
- plt.ylabel('$\Delta AIC$')
- plt.xlabel('Number of Gaussians')
-
- plt.subplot(325)
- plt.bar(np.arange(NGauss)+1,Akaikeweights,facecolor='b',alpha=0.6)
- plt.tight_layout()
- plt.grid(alpha=0.3)
- plt.ylabel('Akaike Weight [%]')
- plt.xlabel('Number of Gaussians')
-
- plt.subplot(3,2,(4,6))
- for i in range(len(Peval)):
- plt.plot(r,P + 2*i,'k',r,Peval[i] + 2*i,'b-',linewidth=1.5)
- plt.tight_layout()
- plt.grid(alpha=0.3)
- plt.xlabel('r [nm]')
- plt.ylabel('Number of Gaussians')
- plt.legend(['truth','fit'])
-
-
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_multigauss_fitting_4pdeer_001.png
- :alt: plot multigauss fitting 4pdeer
- :class: sphx-glr-single-img
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
-
-
-
-
-
-
-.. rst-class:: sphx-glr-timing
-
- **Total running time of the script:** ( 0 minutes 16.126 seconds)
-
-
-.. _sphx_glr_download_auto_examples_plot_multigauss_fitting_4pdeer.py:
-
-
-.. only :: html
-
- .. container:: sphx-glr-footer
- :class: sphx-glr-footer-example
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-python
-
- :download:`Download Python source code: plot_multigauss_fitting_4pdeer.py `
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-jupyter
-
- :download:`Download Jupyter notebook: plot_multigauss_fitting_4pdeer.ipynb `
-
-
-.. only:: html
-
- .. rst-class:: sphx-glr-signature
-
- `Gallery generated by Sphinx-Gallery `_
diff --git a/docsrc/source/auto_examples/plot_multigauss_fitting_4pdeer_codeobj.pickle b/docsrc/source/auto_examples/plot_multigauss_fitting_4pdeer_codeobj.pickle
deleted file mode 100644
index f81ef3955..000000000
Binary files a/docsrc/source/auto_examples/plot_multigauss_fitting_4pdeer_codeobj.pickle and /dev/null differ
diff --git a/docsrc/source/auto_examples/plot_param_uncertainty_propagation.py b/docsrc/source/auto_examples/plot_param_uncertainty_propagation.py
deleted file mode 100644
index 6a94955a5..000000000
--- a/docsrc/source/auto_examples/plot_param_uncertainty_propagation.py
+++ /dev/null
@@ -1,140 +0,0 @@
-
-# %% [markdown]
-"""
-Uncertainty propagation from parameter fits using covariance-based uncertainty quantificaion
-===========================================================================================
-
-How to propagate the uncertainty of the fitted parameters to the models which depend on them.
-"""
-
-import numpy as np
-import matplotlib.pyplot as plt
-from deerlab import *
-
-# %% [markdown]
-# Generate data
-# -------------
-
-t = np.linspace(-0.2,4,300)
-r = np.linspace(2,5,400)
-center = 3.5 # [nm] Rician center distance
-width = 0.3 # [nm] Rician width
-lam = 0.27 # Modulation depth
-conc = 150 # [uM] Spin concentration
-P = dd_rice(r,[center, width])
-B = bg_hom3d(t,conc,lam)
-K = dipolarkernel(t,r,lam,B)
-np.random.seed(0)
-V = K@P + whitegaussnoise(t,0.03)
-
-# %% [markdown]
-# Fit the data
-# ------------
-# First we define the models for the different elements in our analysis
-# (background, distribution and dipolar signal). For simplicity these
-# models take the full parameter set
-#
-# ``par = [lambda center width conc]``
-#
-# and select the appropiate elements from the parameter set, i.e.
-#
-# ``Pmodel = f(center,width) -> par[1] & par[2]``
-# ``Bmodel = f(conc,lambda) -> par[3] & par[0]``
-# ``Vmodel = f(par) -> par[0] & par[1] & par[2] & par[3]``
-#
-# By defining the models like this, we can spare then the indexing of the
-# parameters each time we call one of these model and can pass the full
-# parameter set directly.
-
-# Pre-calculate the elemental dipolar kernel (for speed)
-K0 = dipolarkernel(t,r)
-
-Pmodel = lambda par: dd_rice(r,par[1:3])
-Bmodel = lambda par: bg_hom3d(t,par[3],par[0])
-Vmodel = lambda par: (1 - par[0] + par[0]*K0@Pmodel(par))*Bmodel(par)
-
-# %% [markdown]
-# Next since we are dealing with a custom-defined model we need to specify
-# the start values as well as boundaries of the parameter set:
-
-# Parameters:[lam center width conc]
-par0 = [0.35, 4.0, 0.4, 500 ] # start values
-lower = [0.10, 2.0, 0.1, 0.1 ] # lower bounds
-upper = [0.50, 7.0, 0.5, 1500] # upper bounds
-
-# Finally we can run the fit and get the fitted parameters and their uncertainties
-fit = fitparamodel(V,Vmodel,par0,lower,upper)
-
-parfit = fit.param
-paruq = fit.uncertainty
-
-# Forward-calculate the models with the fitted parameters
-Vfit = Vmodel(parfit)
-Pfit = Pmodel(parfit)
-Bfit = Bmodel(parfit)
-lamfit = parfit[0]
-
-# %% [markdown]
-# Uncertainty propagation
-#------------------------
-# In DeerLab, all uncertainty quantification objects contain a method
-# ``.propagate()``, which has all the internal information on the
-# covariance matrices required to propagate the uncertainty from
-# the parameters to the fits.
-#
-# Thus, all we neeed to do is call ``.propagate``` and pass the model function
-# which we want to propagate the uncertainty to. It is important that if
-# the uncertainty quantification structure is defined for N-parameters (N=4
-# in this case) the model function must accept all N parameters. Since we
-# defined our model function to accept all N parameters already we do not
-# need to worry about it.
-
-# %% [markdown]
-# 1. Uncertainty of the dipolar signal fit: This case is easy, we already have the model and it is unconstrained
-Vuq = paruq.propagate(Vmodel) # Uncertainty quantification for Vfit
-Vci95 = Vuq.ci(95) # 95#-confidence intervals for Vfit
-
-# %% [markdown]
-# 2. Uncertainty of the distance distribution: In this case, the distribution has a non-negativity constraint which we
-# can specify via the lb input.
-lb = np.zeros_like(r) # Non-negativity constraint
-Puq = paruq.propagate(Pmodel,lb) # Uncertainty quantification for Pfit
-Pci95 = Puq.ci(95) # 95#-confidence intervals for Pfit
-
-# %% [markdown]
-# 3. Uncertainty of the background: In this case, since we want to use this for plotting we need to evaluate
-# the function (1-lambda)*Bfit instead of just Bfit in order to plot the\
-# correct function.
-Buq = paruq.propagate(lambda p:(1-p[0])*Bmodel(p)) # Uncertainty quantification for (1-lam)Bfit
-Bci95 = Buq.ci(95) # 95#-confidence intervals for (1-lam)Bfit
-
-# %% [markdown]
-# Plots
-# -----
-
-plt.figure(figsize=(7,7))
-
-# Time-domain
-plt.subplot(211)
-plt.plot(t,V,'k.',t,Vfit,'r',t,(1-lamfit)*Bfit,'b',linewidth=1.5)
-plt.fill_between(t,Vci95[:,0],Vci95[:,1],color='r',alpha=0.3,linestyle='None')
-plt.fill_between(t,Bci95[:,0],Bci95[:,1],color='b',alpha=0.3,linestyle='None')
-plt.grid(alpha=0.3)
-plt.xlabel('t [$\mu s$]')
-plt.ylabel('V(t)')
-plt.legend(['data','Vfit','Bfit','Vfit 95%-CI','Bfit 95%-CI'])
-
-# Distance-domain
-plt.subplot(212)
-plt.plot(r,P,'k',r,Pfit,'r',linewidth=1.5)
-plt.fill_between(r,Pci95[:,0],Pci95[:,1],color='r',alpha=0.3,linestyle='None')
-plt.xlabel('r [nm]')
-plt.ylabel('P(r) [nm$^{-1}$]')
-plt.grid(alpha=0.3)
-plt.legend(['truth','Pfit','Pfit 95%-CI'])
-
-
-# %%
-
-
-# %%
diff --git a/docsrc/source/auto_examples/plot_param_uncertainty_propagation.py.md5 b/docsrc/source/auto_examples/plot_param_uncertainty_propagation.py.md5
deleted file mode 100644
index a7402ba7e..000000000
--- a/docsrc/source/auto_examples/plot_param_uncertainty_propagation.py.md5
+++ /dev/null
@@ -1 +0,0 @@
-1b425eee9afa4166922880d349d51658
\ No newline at end of file
diff --git a/docsrc/source/auto_examples/plot_param_uncertainty_propagation.rst b/docsrc/source/auto_examples/plot_param_uncertainty_propagation.rst
deleted file mode 100644
index 8679b5097..000000000
--- a/docsrc/source/auto_examples/plot_param_uncertainty_propagation.rst
+++ /dev/null
@@ -1,267 +0,0 @@
-.. only:: html
-
- .. note::
- :class: sphx-glr-download-link-note
-
- Click :ref:`here ` to download the full example code
- .. rst-class:: sphx-glr-example-title
-
- .. _sphx_glr_auto_examples_plot_param_uncertainty_propagation.py:
-
-
-Uncertainty propagation from parameter fits using covariance-based uncertainty quantificaion
-===========================================================================================
-
-How to propagate the uncertainty of the fitted parameters to the models which depend on them.
-
-
-.. code-block:: python
-
-
- import numpy as np
- import matplotlib.pyplot as plt
- from deerlab import *
-
-
-
-
-
-
-
-
-Generate data
--------------
-
-
-.. code-block:: python
-
-
- t = np.linspace(-0.2,4,300)
- r = np.linspace(2,5,400)
- center = 3.5 # [nm] Rician center distance
- width = 0.3 # [nm] Rician width
- lam = 0.27 # Modulation depth
- conc = 150 # [uM] Spin concentration
- P = dd_rice(r,[center, width])
- B = bg_hom3d(t,conc,lam)
- K = dipolarkernel(t,r,lam,B)
- np.random.seed(0)
- V = K@P + whitegaussnoise(t,0.03)
-
-
-
-
-
-
-
-
-Fit the data
-------------
-First we define the models for the different elements in our analysis
-(background, distribution and dipolar signal). For simplicity these
-models take the full parameter set
-
-``par = [lambda center width conc]``
-
-and select the appropiate elements from the parameter set, i.e.
-
-``Pmodel = f(center,width) -> par[1] & par[2]``
-``Bmodel = f(conc,lambda) -> par[3] & par[0]``
-``Vmodel = f(par) -> par[0] & par[1] & par[2] & par[3]``
-
-By defining the models like this, we can spare then the indexing of the
-parameters each time we call one of these model and can pass the full
-parameter set directly.
-
-
-.. code-block:: python
-
-
- # Pre-calculate the elemental dipolar kernel (for speed)
- K0 = dipolarkernel(t,r)
-
- Pmodel = lambda par: dd_rice(r,par[1:3])
- Bmodel = lambda par: bg_hom3d(t,par[3],par[0])
- Vmodel = lambda par: (1 - par[0] + par[0]*K0@Pmodel(par))*Bmodel(par)
-
-
-
-
-
-
-
-
-Next since we are dealing with a custom-defined model we need to specify
-the start values as well as boundaries of the parameter set:
-
-
-.. code-block:: python
-
-
- # Parameters:[lam center width conc]
- par0 = [0.35, 4.0, 0.4, 500 ] # start values
- lower = [0.10, 2.0, 0.1, 0.1 ] # lower bounds
- upper = [0.50, 7.0, 0.5, 1500] # upper bounds
-
- # Finally we can run the fit and get the fitted parameters and their uncertainties
- fit = fitparamodel(V,Vmodel,par0,lower,upper)
-
- parfit = fit.param
- paruq = fit.uncertainty
-
- # Forward-calculate the models with the fitted parameters
- Vfit = Vmodel(parfit)
- Pfit = Pmodel(parfit)
- Bfit = Bmodel(parfit)
- lamfit = parfit[0]
-
-
-
-
-
-
-
-
-Uncertainty propagation
-------------------------
- In DeerLab, all uncertainty quantification objects contain a method
- ``.propagate()``, which has all the internal information on the
- covariance matrices required to propagate the uncertainty from
- the parameters to the fits.
-
- Thus, all we neeed to do is call ``.propagate``` and pass the model function
- which we want to propagate the uncertainty to. It is important that if
- the uncertainty quantification structure is defined for N-parameters (N=4
- in this case) the model function must accept all N parameters. Since we
- defined our model function to accept all N parameters already we do not
- need to worry about it.
-
-1. Uncertainty of the dipolar signal fit: This case is easy, we already have the model and it is unconstrained
-
-
-.. code-block:: python
-
- Vuq = paruq.propagate(Vmodel) # Uncertainty quantification for Vfit
- Vci95 = Vuq.ci(95) # 95#-confidence intervals for Vfit
-
-
-
-
-
-
-
-
-2. Uncertainty of the distance distribution: In this case, the distribution has a non-negativity constraint which we
-can specify via the lb input.
-
-
-.. code-block:: python
-
- lb = np.zeros_like(r) # Non-negativity constraint
- Puq = paruq.propagate(Pmodel,lb) # Uncertainty quantification for Pfit
- Pci95 = Puq.ci(95) # 95#-confidence intervals for Pfit
-
-
-
-
-
-
-
-
-3. Uncertainty of the background: In this case, since we want to use this for plotting we need to evaluate
-the function (1-lambda)*Bfit instead of just Bfit in order to plot the\
-correct function.
-
-
-.. code-block:: python
-
- Buq = paruq.propagate(lambda p:(1-p[0])*Bmodel(p)) # Uncertainty quantification for (1-lam)Bfit
- Bci95 = Buq.ci(95) # 95#-confidence intervals for (1-lam)Bfit
-
-
-
-
-
-
-
-
-Plots
------
-
-
-.. code-block:: python
-
-
- plt.figure(figsize=(7,7))
-
- # Time-domain
- plt.subplot(211)
- plt.plot(t,V,'k.',t,Vfit,'r',t,(1-lamfit)*Bfit,'b',linewidth=1.5)
- plt.fill_between(t,Vci95[:,0],Vci95[:,1],color='r',alpha=0.3,linestyle='None')
- plt.fill_between(t,Bci95[:,0],Bci95[:,1],color='b',alpha=0.3,linestyle='None')
- plt.grid(alpha=0.3)
- plt.xlabel('t [$\mu s$]')
- plt.ylabel('V(t)')
- plt.legend(['data','Vfit','Bfit','Vfit 95%-CI','Bfit 95%-CI'])
-
- # Distance-domain
- plt.subplot(212)
- plt.plot(r,P,'k',r,Pfit,'r',linewidth=1.5)
- plt.fill_between(r,Pci95[:,0],Pci95[:,1],color='r',alpha=0.3,linestyle='None')
- plt.xlabel('r [nm]')
- plt.ylabel('P(r) [nm$^{-1}$]')
- plt.grid(alpha=0.3)
- plt.legend(['truth','Pfit','Pfit 95%-CI'])
-
-
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_param_uncertainty_propagation_001.png
- :alt: plot param uncertainty propagation
- :class: sphx-glr-single-img
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
-
-
-
-
-
-
-.. rst-class:: sphx-glr-timing
-
- **Total running time of the script:** ( 0 minutes 2.902 seconds)
-
-
-.. _sphx_glr_download_auto_examples_plot_param_uncertainty_propagation.py:
-
-
-.. only :: html
-
- .. container:: sphx-glr-footer
- :class: sphx-glr-footer-example
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-python
-
- :download:`Download Python source code: plot_param_uncertainty_propagation.py `
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-jupyter
-
- :download:`Download Jupyter notebook: plot_param_uncertainty_propagation.ipynb `
-
-
-.. only:: html
-
- .. rst-class:: sphx-glr-signature
-
- `Gallery generated by Sphinx-Gallery `_
diff --git a/docsrc/source/auto_examples/plot_param_uncertainty_propagation_codeobj.pickle b/docsrc/source/auto_examples/plot_param_uncertainty_propagation_codeobj.pickle
deleted file mode 100644
index b8bffdc4f..000000000
Binary files a/docsrc/source/auto_examples/plot_param_uncertainty_propagation_codeobj.pickle and /dev/null differ
diff --git a/docsrc/source/auto_examples/plot_pseudotitration_parameter_free.py b/docsrc/source/auto_examples/plot_pseudotitration_parameter_free.py
deleted file mode 100644
index 80cab364f..000000000
--- a/docsrc/source/auto_examples/plot_pseudotitration_parameter_free.py
+++ /dev/null
@@ -1,187 +0,0 @@
-# %% [markdown]
-"""
-Analyzing pseudo-titration (dose-respononse) curves with parameter-free distributions
-======================================================================================
-
-How to use separable non-linear least squares (SNLLS)
-to fit a pseudo-titration curve to multiple DEER datsets, using
-parameter-free distance distributions.
-"""
-
-import numpy as np
-import matplotlib.pyplot as plt
-from deerlab import *
-
-# %% [markdown]
-# Generating multiple datasets
-#-----------------------------------------------------------------------------
-# First, let's prepare the chemical desciption of the problem. In this example we will
-# simulate a protein system in their states A (natural) and B (changed upon addition
-# of a ligand L) given by the chemical equilibrium A + L <-> B.
-
-def chemicalequilibrium(Kdis,L):
- """Prepare equilibrium of type: A + L <-> B"""
- Ctot = 1 # total protein concentration, uM
-
- # # Get fraction of state B
- Kb = 1/Kdis
- xB = np.zeros_like(L)
- for q in range(len(L)):
- xB_ = np.roots([Kb*Ctot, -(Kb*L[q] + Kb*Ctot + 1), Kb*L[q]])
- try:
- xB[q] = xB_[(xB_<=1) & (xB_>=0)]
- except:
- xB[q] = np.minimum(1,np.maximum(0,xB_[0]))
- # Get fraction of state A
- xA = 1 - xB
-
- return xA,xB
-
-# %% [markdown]\
-# Next, we define the dipolar kernel model as the non-linear function of the
-# SNLLS problem. This function needs to take the parameters and return a
-# cell-array of kernels, each one for the corresponding datasets that we
-# have.
-# Since we have a total distribution of the form
-# ``P = xA*PA + xB*PB``
-# we can define an augmented kernel as
-# ``K = [xA*KA xB*KB]``
-# such that
-# ``K@[PA PB] = V``
-# and the vector ``[PA PB]`` constitutes the linear part fitted by SNLLS.
-
-def Kmodel(par,ts,rA,rB,L):
-
- Nsignals = len(ts)
-
- # Unpack parameters
- lam,k,Kdis = par
-
- # Get fractions for given KD
- [xA,xB] = chemicalequilibrium(Kdis,L)
-
- Ks = [[]]*Nsignals
- # General the dipolar kernels
- for i in range(Nsignals):
- B = bg_exp(ts[i],k,lam)
- # Kernel for fraction A
- KstateA = dipolarkernel(ts[i],rA,lam,B)
- # Kernel for fraction B
- KstateB = dipolarkernel(ts[i],rB,lam,B)
- Ks[i] = np.concatenate((xA[i]*KstateA, xB[i]*KstateB),axis=1)
-
- return Ks
-
-# %% [markdown]
-# Now, we can simulate multiple signals corresponding to different concentrations
-# of added ligand.
-
-# Time axes
-ts = [[]]*7
-ts[0] = np.linspace(-0.2,3,100)
-ts[1] = np.linspace(-0.1,5,300)
-ts[2] = np.linspace(-0.5,2,200)
-ts[3] = np.linspace(-0.1,1,100)
-ts[4] = np.linspace(-0.2,6,300)
-ts[5] = np.linspace(-0.2,3,300)
-ts[6] = np.linspace(-0.1,4,100)
-Nsignals = len(ts)
-
-# Distance axes for states A and B
-rA = np.linspace(1,8,100)
-rB = np.linspace(1,8,100)
-
-# Distributions for states A and B
-PstateA = dd_gauss(rA,[5.5, 0.4])
-PstateB = dd_gauss2(rB,[4.5, 0.7, 0.4, 3.5, 0.6, 0.6])
-
-L = [0.3, 1, 3, 10, 30, 100, 300] # total ligand concentration, uM
-Kdis = 5.65 # dissociation constant, uM
-
-# Populations of states A and B
-[xA,xB] = chemicalequilibrium(Kdis,L)
-
-# Global kernel model
-Ks = Kmodel([0.25, 0.1, Kdis],ts,rA,rB,L)
-
-# Simulate dipolar signals
-Vs = [[]]*Nsignals
-for i in range(Nsignals):
- np.random.seed(i)
- Vs[i] = Ks[i]@np.concatenate((PstateA, PstateB)) + whitegaussnoise(ts[i],0.005)
-
-# %% [markdown]
-# Psuedotitration SNLLS Analysis
-#-----------------------------------------------------------------------------
-# For simplification, we will assume that all DEER traces have the same
-# background function and modulation depth. Thus, we will fit the
-# modulations depth (lam) and background decay constant (k) globally along
-# the dissociation constant (KD).
-
-# Non-linear parameters:
-# lam k KD
-par0 = [0.5, 0.5, 5] # start values
-lb = [ 0, 0, 1] # lower bounds
-ub = [ 1, 1, 10] # upper bounds
-
-# Linear parameters:
-# |-------PA--------||--------PB--------|
-lbl = np.concatenate((np.zeros_like(rA), np.zeros_like(rB))) # Non-negativity constraint
-ubl = [] # Unconstrained
-
-# Run SNLLS optimization
-fit = snlls(Vs,lambda p: Kmodel(p,ts,rA,rB,L),par0,lb,ub,lbl,ubl)
-# Extract fit results
-parfit = fit.nonlin
-Pfit = fit.lin
-puq = fit.uncertainty
-
-# Extract the fitted disociation constant value and its 95#-confidence interval
-Kdisfit = parfit[2]
-parci = puq.ci(95,'nonlin')
-KDci = parci[2,:]
-
-# Print result
-print('Kdis = {:.2f}({:.2f}-{:.2f})uM'.format(Kdisfit,KDci[0],KDci[1]))
-
-# %%
-# Plot results
-plt.figure(figsize=(12,12))
-
-# Simulate fits
-Ksfit = Kmodel(parfit,ts,rA,rB,L)
-Vsfit = []
-plt.subplot(3,2,(1,3))
-for i in range(Nsignals):
- Vsfit.append(Ksfit[i]@Pfit)
- plt.plot(ts[i],Vs[i]+i/9,'k.',ts[i],Vsfit[i]+i/9,'r',linewidth=1.5)
-plt.grid(alpha =0.3)
-plt.xlabel('t [$\mu s$]')
-plt.ylabel('V(t) [a.u.]')
-plt.legend(['data','fit'])
-
-xAfit,xBfit = chemicalequilibrium(Kdisfit,L)
-plt.subplot(2,2,(2,4))
-for i in range(Nsignals):
- PAfit = xAfit[i]*Pfit[0:len(rA)]
- PBfit = xBfit[i]*Pfit[len(rA):len(rB)+len(rA)]
- plt.plot(rA,PAfit+2*i,'r',rB,PBfit+2*i,'b',linewidth=1.5)
-
-plt.grid(alpha =0.3)
-plt.xlabel('r [nm]')
-plt.ylabel('P(r)')
-plt.legend(['state A','state B'])
-plt.xlim([2,7])
-
-plt.subplot(325)
-plt.plot(np.log10(L),xA,'r-',np.log10(L),xB,'b-')
-plt.plot(np.log10(L),xAfit,'ro',np.log10(L),xBfit,'bo',linewidth=1.5)
-plt.grid(alpha =0.3)
-plt.xlabel('log$_{10}$([L])')
-plt.ylabel('Fractions')
-plt.legend(['state A','state B'])
-plt.ylim([0,1])
-
-
-
-# %%
diff --git a/docsrc/source/auto_examples/plot_pseudotitration_parameter_free.py.md5 b/docsrc/source/auto_examples/plot_pseudotitration_parameter_free.py.md5
deleted file mode 100644
index 3aca4c8d6..000000000
--- a/docsrc/source/auto_examples/plot_pseudotitration_parameter_free.py.md5
+++ /dev/null
@@ -1 +0,0 @@
-cd48d11ca830dc0ca1ed49feec0d4468
\ No newline at end of file
diff --git a/docsrc/source/auto_examples/plot_pseudotitration_parameter_free.rst b/docsrc/source/auto_examples/plot_pseudotitration_parameter_free.rst
deleted file mode 100644
index e874bb9cd..000000000
--- a/docsrc/source/auto_examples/plot_pseudotitration_parameter_free.rst
+++ /dev/null
@@ -1,309 +0,0 @@
-.. only:: html
-
- .. note::
- :class: sphx-glr-download-link-note
-
- Click :ref:`here ` to download the full example code
- .. rst-class:: sphx-glr-example-title
-
- .. _sphx_glr_auto_examples_plot_pseudotitration_parameter_free.py:
-
-
-Analyzing pseudo-titration (dose-respononse) curves with parameter-free distributions
-======================================================================================
-
-How to use separable non-linear least squares (SNLLS)
-to fit a pseudo-titration curve to multiple DEER datsets, using
-parameter-free distance distributions.
-
-
-.. code-block:: python
-
-
- import numpy as np
- import matplotlib.pyplot as plt
- from deerlab import *
-
-
-
-
-
-
-
-
-Generating multiple datasets
------------------------------------------------------------------------------
- First, let's prepare the chemical desciption of the problem. In this example we will
- simulate a protein system in their states A (natural) and B (changed upon addition
- of a ligand L) given by the chemical equilibrium A + L <-> B.
-
-
-.. code-block:: python
-
-
- def chemicalequilibrium(Kdis,L):
- """Prepare equilibrium of type: A + L <-> B"""
- Ctot = 1 # total protein concentration, uM
-
- # # Get fraction of state B
- Kb = 1/Kdis
- xB = np.zeros_like(L)
- for q in range(len(L)):
- xB_ = np.roots([Kb*Ctot, -(Kb*L[q] + Kb*Ctot + 1), Kb*L[q]])
- try:
- xB[q] = xB_[(xB_<=1) & (xB_>=0)]
- except:
- xB[q] = np.minimum(1,np.maximum(0,xB_[0]))
- # Get fraction of state A
- xA = 1 - xB
-
- return xA,xB
-
-
-
-
-
-
-
-
-Next, we define the dipolar kernel model as the non-linear function of the
-SNLLS problem. This function needs to take the parameters and return a
-cell-array of kernels, each one for the corresponding datasets that we
-have.
-Since we have a total distribution of the form
- ``P = xA*PA + xB*PB``
-we can define an augmented kernel as
- ``K = [xA*KA xB*KB]``
-such that
- ``K@[PA PB] = V``
-and the vector ``[PA PB]`` constitutes the linear part fitted by SNLLS.
-
-
-.. code-block:: python
-
-
- def Kmodel(par,ts,rA,rB,L):
-
- Nsignals = len(ts)
-
- # Unpack parameters
- lam,k,Kdis = par
-
- # Get fractions for given KD
- [xA,xB] = chemicalequilibrium(Kdis,L)
-
- Ks = [[]]*Nsignals
- # General the dipolar kernels
- for i in range(Nsignals):
- B = bg_exp(ts[i],k,lam)
- # Kernel for fraction A
- KstateA = dipolarkernel(ts[i],rA,lam,B)
- # Kernel for fraction B
- KstateB = dipolarkernel(ts[i],rB,lam,B)
- Ks[i] = np.concatenate((xA[i]*KstateA, xB[i]*KstateB),axis=1)
-
- return Ks
-
-
-
-
-
-
-
-
-Now, we can simulate multiple signals corresponding to different concentrations
-of added ligand.
-
-
-.. code-block:: python
-
-
- # Time axes
- ts = [[]]*7
- ts[0] = np.linspace(-0.2,3,100)
- ts[1] = np.linspace(-0.1,5,300)
- ts[2] = np.linspace(-0.5,2,200)
- ts[3] = np.linspace(-0.1,1,100)
- ts[4] = np.linspace(-0.2,6,300)
- ts[5] = np.linspace(-0.2,3,300)
- ts[6] = np.linspace(-0.1,4,100)
- Nsignals = len(ts)
-
- # Distance axes for states A and B
- rA = np.linspace(1,8,100)
- rB = np.linspace(1,8,100)
-
- # Distributions for states A and B
- PstateA = dd_gauss(rA,[5.5, 0.4])
- PstateB = dd_gauss2(rB,[4.5, 0.7, 0.4, 3.5, 0.6, 0.6])
-
- L = [0.3, 1, 3, 10, 30, 100, 300] # total ligand concentration, uM
- Kdis = 5.65 # dissociation constant, uM
-
- # Populations of states A and B
- [xA,xB] = chemicalequilibrium(Kdis,L)
-
- # Global kernel model
- Ks = Kmodel([0.25, 0.1, Kdis],ts,rA,rB,L)
-
- # Simulate dipolar signals
- Vs = [[]]*Nsignals
- for i in range(Nsignals):
- np.random.seed(i)
- Vs[i] = Ks[i]@np.concatenate((PstateA, PstateB)) + whitegaussnoise(ts[i],0.005)
-
-
-
-
-
-
-
-
-Psuedotitration SNLLS Analysis
------------------------------------------------------------------------------
- For simplification, we will assume that all DEER traces have the same
- background function and modulation depth. Thus, we will fit the
- modulations depth (lam) and background decay constant (k) globally along
- the dissociation constant (KD).
-
-
-.. code-block:: python
-
-
- # Non-linear parameters:
- # lam k KD
- par0 = [0.5, 0.5, 5] # start values
- lb = [ 0, 0, 1] # lower bounds
- ub = [ 1, 1, 10] # upper bounds
-
- # Linear parameters:
- # |-------PA--------||--------PB--------|
- lbl = np.concatenate((np.zeros_like(rA), np.zeros_like(rB))) # Non-negativity constraint
- ubl = [] # Unconstrained
-
- # Run SNLLS optimization
- fit = snlls(Vs,lambda p: Kmodel(p,ts,rA,rB,L),par0,lb,ub,lbl,ubl)
- # Extract fit results
- parfit = fit.nonlin
- Pfit = fit.lin
- puq = fit.uncertainty
-
- # Extract the fitted disociation constant value and its 95#-confidence interval
- Kdisfit = parfit[2]
- parci = puq.ci(95,'nonlin')
- KDci = parci[2,:]
-
- # Print result
- print('Kdis = {:.2f}({:.2f}-{:.2f})uM'.format(Kdisfit,KDci[0],KDci[1]))
-
-
-
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
- D:\lufa\projects\DeerLab\DeerLab\examples\plot_pseudotitration_parameter_free.py:34: ComplexWarning: Casting complex values to real discards the imaginary part
- xB[q] = np.minimum(1,np.maximum(0,xB_[0]))
- Kdis = 5.33(5.04-5.63)uM
-
-
-
-
-Plot results
-
-
-.. code-block:: python
-
- plt.figure(figsize=(12,12))
-
- # Simulate fits
- Ksfit = Kmodel(parfit,ts,rA,rB,L)
- Vsfit = []
- plt.subplot(3,2,(1,3))
- for i in range(Nsignals):
- Vsfit.append(Ksfit[i]@Pfit)
- plt.plot(ts[i],Vs[i]+i/9,'k.',ts[i],Vsfit[i]+i/9,'r',linewidth=1.5)
- plt.grid(alpha =0.3)
- plt.xlabel('t [$\mu s$]')
- plt.ylabel('V(t) [a.u.]')
- plt.legend(['data','fit'])
-
- xAfit,xBfit = chemicalequilibrium(Kdisfit,L)
- plt.subplot(2,2,(2,4))
- for i in range(Nsignals):
- PAfit = xAfit[i]*Pfit[0:len(rA)]
- PBfit = xBfit[i]*Pfit[len(rA):len(rB)+len(rA)]
- plt.plot(rA,PAfit+2*i,'r',rB,PBfit+2*i,'b',linewidth=1.5)
-
- plt.grid(alpha =0.3)
- plt.xlabel('r [nm]')
- plt.ylabel('P(r)')
- plt.legend(['state A','state B'])
- plt.xlim([2,7])
-
- plt.subplot(325)
- plt.plot(np.log10(L),xA,'r-',np.log10(L),xB,'b-')
- plt.plot(np.log10(L),xAfit,'ro',np.log10(L),xBfit,'bo',linewidth=1.5)
- plt.grid(alpha =0.3)
- plt.xlabel('log$_{10}$([L])')
- plt.ylabel('Fractions')
- plt.legend(['state A','state B'])
- plt.ylim([0,1])
-
-
-
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_pseudotitration_parameter_free_001.png
- :alt: plot pseudotitration parameter free
- :class: sphx-glr-single-img
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
-
- (0.0, 1.0)
-
-
-
-
-.. rst-class:: sphx-glr-timing
-
- **Total running time of the script:** ( 0 minutes 26.262 seconds)
-
-
-.. _sphx_glr_download_auto_examples_plot_pseudotitration_parameter_free.py:
-
-
-.. only :: html
-
- .. container:: sphx-glr-footer
- :class: sphx-glr-footer-example
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-python
-
- :download:`Download Python source code: plot_pseudotitration_parameter_free.py `
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-jupyter
-
- :download:`Download Jupyter notebook: plot_pseudotitration_parameter_free.ipynb `
-
-
-.. only:: html
-
- .. rst-class:: sphx-glr-signature
-
- `Gallery generated by Sphinx-Gallery `_
diff --git a/docsrc/source/auto_examples/plot_pseudotitration_parameter_free_codeobj.pickle b/docsrc/source/auto_examples/plot_pseudotitration_parameter_free_codeobj.pickle
deleted file mode 100644
index cc7ebe471..000000000
Binary files a/docsrc/source/auto_examples/plot_pseudotitration_parameter_free_codeobj.pickle and /dev/null differ
diff --git a/docsrc/source/auto_examples/plot_selecting_an_optimal_model.py b/docsrc/source/auto_examples/plot_selecting_an_optimal_model.py
deleted file mode 100644
index afb1be8fa..000000000
--- a/docsrc/source/auto_examples/plot_selecting_an_optimal_model.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# %% [markdown]
-"""
-Selecting an optimal parametric model for fitting a dipolar signal
-==================================================================
-
-How to optimally select a parametric model for a given dipolar signal.
-"""
-
-import numpy as np
-import matplotlib.pyplot as plt
-from deerlab import *
-
-# %% [markdown]
-# Data Generation
-# ----------------
-#
-# Let's start by constructing a simple dipolar signal with some noise arising
-# from a bimodal Gaussian distance distribution.
-
-# Prepare the signal components
-t = np.linspace(-0.3,6,300)
-r = np.linspace(2,6,200)
-P = dd_gauss2(r,[3.8, 0.7, 0.7, 4.5, 0.3, 0.7])
-
-# Prepare the dipolar kernel and get the signal
-K = dipolarkernel(t,r)
-V = K@P + whitegaussnoise(t,0.01)
-
-# %% [markdown]
-# Selecting an optimal model
-# --------------------------
-#
-# Even though we know the ground truth, in this example we will cosider the
-# following set of potential parametric models:
-#
-# * Unimodal Rician distribution
-# * Bimodal Rician distribution
-# * Trimodal Rician distribution
-# * Unimodal Gaussian distribution
-# * Bimodal Gaussian distribution
-# * Trimodal Gaussian distribution
-# * Mixed bimodal Gaussian/Rician distribution
-#
-# The first six models have built-in parametric models which we can use directly.
-# The last model we can construct from built-in models using the ``mixmodels`` function.
-
-# Prepare the mixed model
-dd_rice_gauss = mixmodels(dd_rice,dd_gauss)
-
-# Prepare list of candidate parametric models
-models = [dd_rice,dd_rice2,dd_rice3,dd_gauss,dd_gauss2,dd_gauss3,dd_rice_gauss]
-
-# %% [markdown]
-# In order to make an appropiate choice, we need some liklihood estimator. All fit functions is DeerLab returns a stats
-# dictionary which contains (amongst other estimators) likelihood estimators such as the Akaike information criterion (AIC).
-# The model with the lowers AIC value can be considered to most likely to be the optimal model.
-#
-# To do this, we jus have to evaluate the parametric models with ``fitparamodel`` while looping over all the distribution models
-# we listed above, and collecting the AIC-values for each model.
-
-aic = []
-for model in models:
- info = model()
- # Prepare the signal model with the new distance model
- Vmodel = lambda par: K@model(r,par)
- # Fit the signal
- fit = fitparamodel(V,Vmodel,par0=info['Start'],lb=info['Lower'],ub=info['Upper'])
- parfit = fit.param
- stats= fit.stats
- # Add current AIC value to the list
- aic.append(stats['aic'])
-
-# %% [markdown]
-# Since the absolute AIC values have no meaning, it is standard practice to look at the relative
-# changes in AIC values between the evaluated models.
-
-daic = aic - min(aic)
-
-# %% [markdown]
-# Akaike Weights
-#-----------------------------------------------------------------------------
-# It is often more useful to look at these results from the perspective of
-# Akaike weights, i.e. the probabilities of a model being the most optimal.
-
-weights = 100*np.exp(-(daic/2))/sum(np.exp(-daic/2))
-
-# %% [markdown]
-# Plot results
-# ------------
-
-plt.figure(figsize=(9,8))
-
-plt.subplot(2,2,1)
-plt.plot(t,V,'k.')
-plt.grid(alpha=0.2)
-plt.xlabel('t [$\mu s$]')
-plt.ylabel('V(t)')
-plt.legend(['data'])
-
-plt.subplot(2,2,2)
-plt.plot(r,P,'k',linewidth=1.5)
-plt.xlabel('r [nm]')
-plt.ylabel('P(r) [nm$^{-1}$]')
-plt.legend(['Ground truth'])
-plt.grid(alpha=0.2)
-
-modelnames = [model.__name__ for model in models]
-
-plt.subplot(2,2,3)
-plt.bar(modelnames,daic,color='b',alpha=0.5)
-plt.ylabel('$\Delta$AIC')
-plt.grid(alpha=0.2)
-plt.xticks(rotation=45)
-
-# Plot the results
-plt.subplot(2,2,4)
-plt.bar(modelnames,weights,color='b',alpha=0.5)
-plt.ylabel('Akaike Weights [%]')
-plt.xticks(rotation=45)
-plt.grid(alpha=0.2)
-
-# %% [markdown]
-# Typically there is not a single optimal model unless the noise level is very
-# low. Usually several models have similar probabilities and should therefore be presented together.
-
-
-# %%
diff --git a/docsrc/source/auto_examples/plot_selecting_an_optimal_model.py.md5 b/docsrc/source/auto_examples/plot_selecting_an_optimal_model.py.md5
deleted file mode 100644
index afd353bb9..000000000
--- a/docsrc/source/auto_examples/plot_selecting_an_optimal_model.py.md5
+++ /dev/null
@@ -1 +0,0 @@
-7f3f18c30e0473de01226ae330cb98d1
\ No newline at end of file
diff --git a/docsrc/source/auto_examples/plot_selecting_an_optimal_model.rst b/docsrc/source/auto_examples/plot_selecting_an_optimal_model.rst
deleted file mode 100644
index d29e32fc8..000000000
--- a/docsrc/source/auto_examples/plot_selecting_an_optimal_model.rst
+++ /dev/null
@@ -1,254 +0,0 @@
-.. only:: html
-
- .. note::
- :class: sphx-glr-download-link-note
-
- Click :ref:`here ` to download the full example code
- .. rst-class:: sphx-glr-example-title
-
- .. _sphx_glr_auto_examples_plot_selecting_an_optimal_model.py:
-
-
-Selecting an optimal parametric model for fitting a dipolar signal
-==================================================================
-
-How to optimally select a parametric model for a given dipolar signal.
-
-
-.. code-block:: python
-
-
- import numpy as np
- import matplotlib.pyplot as plt
- from deerlab import *
-
-
-
-
-
-
-
-
-Data Generation
-----------------
-
-Let's start by constructing a simple dipolar signal with some noise arising
-from a bimodal Gaussian distance distribution.
-
-
-.. code-block:: python
-
-
- # Prepare the signal components
- t = np.linspace(-0.3,6,300)
- r = np.linspace(2,6,200)
- P = dd_gauss2(r,[3.8, 0.7, 0.7, 4.5, 0.3, 0.7])
-
- # Prepare the dipolar kernel and get the signal
- K = dipolarkernel(t,r)
- V = K@P + whitegaussnoise(t,0.01)
-
-
-
-
-
-
-
-
-Selecting an optimal model
---------------------------
-
-Even though we know the ground truth, in this example we will cosider the
-following set of potential parametric models:
-
-* Unimodal Rician distribution
-* Bimodal Rician distribution
-* Trimodal Rician distribution
-* Unimodal Gaussian distribution
-* Bimodal Gaussian distribution
-* Trimodal Gaussian distribution
-* Mixed bimodal Gaussian/Rician distribution
-
-The first six models have built-in parametric models which we can use directly.
-The last model we can construct from built-in models using the ``mixmodels`` function.
-
-
-.. code-block:: python
-
-
- # Prepare the mixed model
- dd_rice_gauss = mixmodels(dd_rice,dd_gauss)
-
- # Prepare list of candidate parametric models
- models = [dd_rice,dd_rice2,dd_rice3,dd_gauss,dd_gauss2,dd_gauss3,dd_rice_gauss]
-
-
-
-
-
-
-
-
-In order to make an appropiate choice, we need some liklihood estimator. All fit functions is DeerLab returns a stats
-dictionary which contains (amongst other estimators) likelihood estimators such as the Akaike information criterion (AIC).
-The model with the lowers AIC value can be considered to most likely to be the optimal model.
-
-To do this, we jus have to evaluate the parametric models with ``fitparamodel`` while looping over all the distribution models
-we listed above, and collecting the AIC-values for each model.
-
-
-.. code-block:: python
-
-
- aic = []
- for model in models:
- info = model()
- # Prepare the signal model with the new distance model
- Vmodel = lambda par: K@model(r,par)
- # Fit the signal
- fit = fitparamodel(V,Vmodel,par0=info['Start'],lb=info['Lower'],ub=info['Upper'])
- parfit = fit.param
- stats= fit.stats
- # Add current AIC value to the list
- aic.append(stats['aic'])
-
-
-
-
-
-.. rst-class:: sphx-glr-script-out
-
- Out:
-
- .. code-block:: none
-
- d:\lufa\projects\deerlab\deerlab\deerlab\fitparamodel.py:197: UserWarning: The fitted value of parameter #5, is at the lower bound of the range.
- warnings.warn('The fitted value of parameter #{}, is at the lower bound of the range.'.format(p))
- d:\lufa\projects\deerlab\deerlab\deerlab\utils\gof.py:54: RuntimeWarning: divide by zero encountered in double_scalars
- R2 = 1 - np.sum((x-xfit)**2)/np.sum((xfit-np.mean(xfit))**2)
- d:\lufa\projects\deerlab\deerlab\deerlab\fitparamodel.py:197: UserWarning: The fitted value of parameter #8, is at the lower bound of the range.
- warnings.warn('The fitted value of parameter #{}, is at the lower bound of the range.'.format(p))
- d:\lufa\projects\deerlab\deerlab\deerlab\utils\gof.py:54: RuntimeWarning: divide by zero encountered in double_scalars
- R2 = 1 - np.sum((x-xfit)**2)/np.sum((xfit-np.mean(xfit))**2)
-
-
-
-
-Since the absolute AIC values have no meaning, it is standard practice to look at the relative
-changes in AIC values between the evaluated models.
-
-
-.. code-block:: python
-
-
- daic = aic - min(aic)
-
-
-
-
-
-
-
-
-Akaike Weights
------------------------------------------------------------------------------
- It is often more useful to look at these results from the perspective of
- Akaike weights, i.e. the probabilities of a model being the most optimal.
-
-
-.. code-block:: python
-
-
- weights = 100*np.exp(-(daic/2))/sum(np.exp(-daic/2))
-
-
-
-
-
-
-
-
-Plot results
-------------
-
-
-.. code-block:: python
-
-
- plt.figure(figsize=(9,8))
-
- plt.subplot(2,2,1)
- plt.plot(t,V,'k.')
- plt.grid(alpha=0.2)
- plt.xlabel('t [$\mu s$]')
- plt.ylabel('V(t)')
- plt.legend(['data'])
-
- plt.subplot(2,2,2)
- plt.plot(r,P,'k',linewidth=1.5)
- plt.xlabel('r [nm]')
- plt.ylabel('P(r) [nm$^{-1}$]')
- plt.legend(['Ground truth'])
- plt.grid(alpha=0.2)
-
- modelnames = [model.__name__ for model in models]
-
- plt.subplot(2,2,3)
- plt.bar(modelnames,daic,color='b',alpha=0.5)
- plt.ylabel('$\Delta$AIC')
- plt.grid(alpha=0.2)
- plt.xticks(rotation=45)
-
- # Plot the results
- plt.subplot(2,2,4)
- plt.bar(modelnames,weights,color='b',alpha=0.5)
- plt.ylabel('Akaike Weights [%]')
- plt.xticks(rotation=45)
- plt.grid(alpha=0.2)
-
-
-
-
-.. image:: /auto_examples/images/sphx_glr_plot_selecting_an_optimal_model_001.png
- :alt: plot selecting an optimal model
- :class: sphx-glr-single-img
-
-
-
-
-
-Typically there is not a single optimal model unless the noise level is very
-low. Usually several models have similar probabilities and should therefore be presented together.
-
-
-.. rst-class:: sphx-glr-timing
-
- **Total running time of the script:** ( 0 minutes 6.839 seconds)
-
-
-.. _sphx_glr_download_auto_examples_plot_selecting_an_optimal_model.py:
-
-
-.. only :: html
-
- .. container:: sphx-glr-footer
- :class: sphx-glr-footer-example
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-python
-
- :download:`Download Python source code: plot_selecting_an_optimal_model.py `
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-jupyter
-
- :download:`Download Jupyter notebook: plot_selecting_an_optimal_model.ipynb `
-
-
-.. only:: html
-
- .. rst-class:: sphx-glr-signature
-
- `Gallery generated by Sphinx-Gallery `_
diff --git a/docsrc/source/auto_examples/plot_selecting_an_optimal_model_codeobj.pickle b/docsrc/source/auto_examples/plot_selecting_an_optimal_model_codeobj.pickle
deleted file mode 100644
index 504708ef9..000000000
Binary files a/docsrc/source/auto_examples/plot_selecting_an_optimal_model_codeobj.pickle and /dev/null differ
diff --git a/docsrc/source/auto_examples/plt_multigauss_fitting_4pdeer.py b/docsrc/source/auto_examples/plt_multigauss_fitting_4pdeer.py
deleted file mode 100644
index fde8bb77b..000000000
--- a/docsrc/source/auto_examples/plt_multigauss_fitting_4pdeer.py
+++ /dev/null
@@ -1,136 +0,0 @@
-# %% [markdown]
-"""
-Multi-Gauss fit of a 4-pulse DEER signal
-----------------------------------------
-
-This example showcases how to fit a simple 4-pulse DEER signal with
-background using a multi-Gauss model, i.e automatically optimizing the
-number of Gaussians in the model.
-"""
-import numpy as np
-import matplotlib.pyplot as plt
-from deerlab import *
-
-
-# %% [markdown]
-# Model function for a 4pDEER dipolar kernel
-# ------------------------------------------
-# The first step for this analysis requires the definition of a parametric dipolar kernel
-# for the description of a 4-pulse DEER experiment.
-
-def K4pdeer(par,t,r):
-
- # Unpack parameters
- lam,conc = par
- # Simualte background
- B = bg_hom3d(t,conc,lam)
- # Generate dipolar kernel
- K = dipolarkernel(t,r,lam,B)
-
- return K
-
-# %% [markdown]
-# Generating a dataset
-# ---------------------
-
-# %%
-t = np.linspace(-0.25,4,300) # time axis, us
-r = np.linspace(2.5,4.5,300) # distance axis, nm
-param0 = [3, 0.3, 0.2, 3.5, 0.3, 0.45, 3.9, 0.2, 0.20] # parameters for three-Gaussian model
-P = dd_gauss3(r,param0) # ground truth distance distribution
-lam = 0.3 # modulation depth
-conc = 250 # spin concentration, uM
-noiselvl = 0.005 # noise level
-
-# Generate 4pDEER dipolar signal with noise
-np.random.seed(0)
-V = K4pdeer([lam,conc],t,r)@P + whitegaussnoise(t,noiselvl)
-
-# %% [markdown]
-# Multi-Gauss fitting
-# -------------------
-
-# Parameter bounds:
-# lambda conc rmean fwhm
-lb = [1, 0.05] # distribution basis function lower bounds
-ub = [20, 5] # distribution basis function upper bounds
-lbK = [0, 0.05] # kernel parameters lower bounds
-ubK = [1, 1500] # kernel parameters upper bounds
-
-# Prepare the kernel model
-Kmodel = lambda par: K4pdeer(par,t,r)
-NGauss = 5 # maximum number of Gaussians
-
-# Fit the kernel parameters with an optimized multi-Gauss distribution
-Pfit,param,Puq,paramuq, metrics, Peval, stats = fitmultimodel(V,Kmodel,r,dd_gauss,NGauss,'aic',lb,ub,lbK,ubK)
-
-# Extract the parameters
-Kparfit = param[0]
-
-# Get the time-domain fit
-K = Kmodel(param[0])
-Vfit = K@Pfit
-
-# Confidence intervals of the fitted distance distribution
-Pci95 = Puq.ci(95) # 95#-confidence interval
-Pci50 = Puq.ci(50) # 50#-confidence interval
-
-# %% [markdown]
-# Akaike weights
-#-----------------------------------------------------------------------------
-# When comparing different parametric models is always a good idea to look
-# at the Akaike weights for each model. They basically tell you the
-# probability of a model being the most optimal choice.
-
-# Compute the Akaike weights
-dAIC = metrics - min(metrics)
-Akaikeweights = 100*np.exp(-dAIC/2)/sum(np.exp(-dAIC/2))
-print(dAIC)
-# %%
-
-# Plots
-plt.figure(figsize=(10,5))
-
-plt.subplot(3,2,1)
-plt.plot(t,V,'k.')
-plt.plot(t,Vfit,'b',linewidth=1.5)
-plt.plot(t,(1-Kparfit[0])*bg_hom3d(t,Kparfit[1],Kparfit[0]),'b--',linewidth=1.5)
-plt.tight_layout()
-plt.grid()
-plt.legend(['data','Vfit','Bfit'])
-plt.xlabel('t [$\mu s$]')
-plt.ylabel('V(t)')
-
-plt.subplot(322)
-plt.plot(r,P,'k',linewidth=1.5)
-plt.plot(r,Pfit,'b',linewidth=1.5)
-plt.fill_between(r,Pci50[:,0],Pci50[:,1],color='b',linestyle='None',alpha=0.45)
-plt.fill_between(r,Pci95[:,0],Pci95[:,1],color='b',linestyle='None',alpha=0.25)
-plt.tight_layout()
-plt.grid()
-plt.legend(['truth','optimal fit','95%-CI'])
-plt.xlabel('r [nm]')
-plt.ylabel('P(r)')
-
-plt.subplot(323)
-plt.bar(np.arange(NGauss)+1,metrics + abs(min(metrics)),facecolor='b',alpha=0.6)
-plt.tight_layout()
-plt.grid()
-plt.ylabel('$\Delta AIC$')
-plt.xlabel('Number of Gaussians')
-
-plt.subplot(325)
-plt.bar(np.arange(NGauss)+1,Akaikeweights,facecolor='b',alpha=0.6)
-plt.tight_layout()
-plt.grid()
-plt.ylabel('Akaike Weight [%]')
-plt.xlabel('Number of Gaussians')
-
-plt.subplot(3,2,(4,6))
-for i in range(len(Peval)):
- plt.plot(r,P + 2*i,'k',r,Peval[i] + 2*i,'b-',linewidth=1.5)
-plt.tight_layout()
-plt.grid()
-plt.xlabel('r [nm]')
-plt.ylabel('Number of Gaussians')
-plt.legend(['truth','fit'])
diff --git a/docsrc/source/auto_examples/plt_multigauss_fitting_4pdeer.rst b/docsrc/source/auto_examples/plt_multigauss_fitting_4pdeer.rst
deleted file mode 100644
index bfa387d7a..000000000
--- a/docsrc/source/auto_examples/plt_multigauss_fitting_4pdeer.rst
+++ /dev/null
@@ -1,198 +0,0 @@
-.. only:: html
-
- .. note::
- :class: sphx-glr-download-link-note
-
- Click :ref:`here ` to download the full example code
- .. rst-class:: sphx-glr-example-title
-
- .. _sphx_glr_auto_examples_plt_multigauss_fitting_4pdeer.py:
-
-
-Multi-Gauss fit of a 4-pulse DEER signal
-----------------------------------------
-
-This example showcases how to fit a simple 4-pulse DEER signal with
-background using a multi-Gauss model, i.e automatically optimizing the
-number of Gaussians in the model.
-
-
-.. code-block:: python
-
- import numpy as np
- import matplotlib.pyplot as plt
- from deerlab import *
-
-
-
-Model function for a 4pDEER dipolar kernel
-------------------------------------------
-The first step for this analysis requires the definition of a parametric dipolar kernel
-for the description of a 4-pulse DEER experiment.
-
-
-.. code-block:: python
-
-
- def K4pdeer(par,t,r):
-
- # Unpack parameters
- lam,conc = par
- # Simualte background
- B = bg_hom3d(t,conc,lam)
- # Generate dipolar kernel
- K = dipolarkernel(t,r,lam,B)
-
- return K
-
-
-Generating a dataset
----------------------
-
-
-.. code-block:: python
-
- t = np.linspace(-0.25,4,300) # time axis, us
- r = np.linspace(2.5,4.5,300) # distance axis, nm
- param0 = [3, 0.3, 0.2, 3.5, 0.3, 0.45, 3.9, 0.2, 0.20] # parameters for three-Gaussian model
- P = dd_gauss3(r,param0) # ground truth distance distribution
- lam = 0.3 # modulation depth
- conc = 250 # spin concentration, uM
- noiselvl = 0.005 # noise level
-
- # Generate 4pDEER dipolar signal with noise
- np.random.seed(0)
- V = K4pdeer([lam,conc],t,r)@P + whitegaussnoise(t,noiselvl)
-
-
-Multi-Gauss fitting
--------------------
-
-
-.. code-block:: python
-
-
- # Parameter bounds:
- # lambda conc rmean fwhm
- lb = [1, 0.05] # distribution basis function lower bounds
- ub = [20, 5] # distribution basis function upper bounds
- lbK = [0, 0.05] # kernel parameters lower bounds
- ubK = [1, 1500] # kernel parameters upper bounds
-
- # Prepare the kernel model
- Kmodel = lambda par: K4pdeer(par,t,r)
- NGauss = 5 # maximum number of Gaussians
-
- # Fit the kernel parameters with an optimized multi-Gauss distribution
- Pfit,param,Puq,paramuq, metrics, Peval, stats = fitmultimodel(V,Kmodel,r,dd_gauss,NGauss,'aic',lb,ub,lbK,ubK)
-
- # Extract the parameters
- Kparfit = param[0]
-
- # Get the time-domain fit
- K = Kmodel(param[0])
- Vfit = K@Pfit
-
- # Confidence intervals of the fitted distance distribution
- Pci95 = Puq.ci(95) # 95#-confidence interval
- Pci50 = Puq.ci(50) # 50#-confidence interval
-
-
-Akaike weights
------------------------------------------------------------------------------
- When comparing different parametric models is always a good idea to look
- at the Akaike weights for each model. They basically tell you the
- probability of a model being the most optimal choice.
-
-
-.. code-block:: python
-
-
- # Compute the Akaike weights
- dAIC = metrics - min(metrics)
- Akaikeweights = 100*np.exp(-dAIC/2)/sum(np.exp(-dAIC/2))
- print(dAIC)
-
-
-.. code-block:: python
-
-
- # Plots
- plt.figure(figsize=(10,5))
-
- plt.subplot(3,2,1)
- plt.plot(t,V,'k.')
- plt.plot(t,Vfit,'b',linewidth=1.5)
- plt.plot(t,(1-Kparfit[0])*bg_hom3d(t,Kparfit[1],Kparfit[0]),'b--',linewidth=1.5)
- plt.tight_layout()
- plt.grid()
- plt.legend(['data','Vfit','Bfit'])
- plt.xlabel('t [$\mu s$]')
- plt.ylabel('V(t)')
-
- plt.subplot(322)
- plt.plot(r,P,'k',linewidth=1.5)
- plt.plot(r,Pfit,'b',linewidth=1.5)
- plt.fill_between(r,Pci50[:,0],Pci50[:,1],color='b',linestyle='None',alpha=0.45)
- plt.fill_between(r,Pci95[:,0],Pci95[:,1],color='b',linestyle='None',alpha=0.25)
- plt.tight_layout()
- plt.grid()
- plt.legend(['truth','optimal fit','95%-CI'])
- plt.xlabel('r [nm]')
- plt.ylabel('P(r)')
-
- plt.subplot(323)
- plt.bar(np.arange(NGauss)+1,metrics + abs(min(metrics)),facecolor='b',alpha=0.6)
- plt.tight_layout()
- plt.grid()
- plt.ylabel('$\Delta AIC$')
- plt.xlabel('Number of Gaussians')
-
- plt.subplot(325)
- plt.bar(np.arange(NGauss)+1,Akaikeweights,facecolor='b',alpha=0.6)
- plt.tight_layout()
- plt.grid()
- plt.ylabel('Akaike Weight [%]')
- plt.xlabel('Number of Gaussians')
-
- plt.subplot(3,2,(4,6))
- for i in range(len(Peval)):
- plt.plot(r,P + 2*i,'k',r,Peval[i] + 2*i,'b-',linewidth=1.5)
- plt.tight_layout()
- plt.grid()
- plt.xlabel('r [nm]')
- plt.ylabel('Number of Gaussians')
- plt.legend(['truth','fit'])
-
-
-.. rst-class:: sphx-glr-timing
-
- **Total running time of the script:** ( 0 minutes 0.000 seconds)
-
-
-.. _sphx_glr_download_auto_examples_plt_multigauss_fitting_4pdeer.py:
-
-
-.. only :: html
-
- .. container:: sphx-glr-footer
- :class: sphx-glr-footer-example
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-python
-
- :download:`Download Python source code: plt_multigauss_fitting_4pdeer.py `
-
-
-
- .. container:: sphx-glr-download sphx-glr-download-jupyter
-
- :download:`Download Jupyter notebook: plt_multigauss_fitting_4pdeer.ipynb `
-
-
-.. only:: html
-
- .. rst-class:: sphx-glr-signature
-
- `Gallery generated by Sphinx-Gallery `_
diff --git a/docsrc/source/auto_examples/plt_multigauss_fitting_4pdeer_codeobj.pickle b/docsrc/source/auto_examples/plt_multigauss_fitting_4pdeer_codeobj.pickle
deleted file mode 100644
index c813a65f1..000000000
Binary files a/docsrc/source/auto_examples/plt_multigauss_fitting_4pdeer_codeobj.pickle and /dev/null differ
diff --git a/docsrc/source/auto_examples/sg_execution_times.rst b/docsrc/source/auto_examples/sg_execution_times.rst
deleted file mode 100644
index 00d71b4a0..000000000
--- a/docsrc/source/auto_examples/sg_execution_times.rst
+++ /dev/null
@@ -1,38 +0,0 @@
-
-:orphan:
-
-.. _sphx_glr_auto_examples_sg_execution_times:
-
-Computation times
-=================
-**00:06.839** total execution time for **auto_examples** files:
-
-+-------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------+
-| :ref:`sphx_glr_auto_examples_plot_selecting_an_optimal_model.py` (``plot_selecting_an_optimal_model.py``) | 00:06.839 | 0.0 MB |
-+-------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------+
-| :ref:`sphx_glr_auto_examples_plot_analyzing_pake_pattern.py` (``plot_analyzing_pake_pattern.py``) | 00:00.000 | 0.0 MB |
-+-------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------+
-| :ref:`sphx_glr_auto_examples_plot_bootstrapped_parameter_distributions.py` (``plot_bootstrapped_parameter_distributions.py``) | 00:00.000 | 0.0 MB |
-+-------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------+
-| :ref:`sphx_glr_auto_examples_plot_comparing_uncertainties_for_regularization.py` (``plot_comparing_uncertainties_for_regularization.py``) | 00:00.000 | 0.0 MB |
-+-------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------+
-| :ref:`sphx_glr_auto_examples_plot_emulating_deeranalysis_workflow.py` (``plot_emulating_deeranalysis_workflow.py``) | 00:00.000 | 0.0 MB |
-+-------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------+
-| :ref:`sphx_glr_auto_examples_plot_extracting_gauss_constraints.py` (``plot_extracting_gauss_constraints.py``) | 00:00.000 | 0.0 MB |
-+-------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------+
-| :ref:`sphx_glr_auto_examples_plot_fitting_4pdeer.py` (``plot_fitting_4pdeer.py``) | 00:00.000 | 0.0 MB |
-+-------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------+
-| :ref:`sphx_glr_auto_examples_plot_fitting_5pdeer.py` (``plot_fitting_5pdeer.py``) | 00:00.000 | 0.0 MB |
-+-------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------+
-| :ref:`sphx_glr_auto_examples_plot_fitting_custom_kernel_with_snlls.py` (``plot_fitting_custom_kernel_with_snlls.py``) | 00:00.000 | 0.0 MB |
-+-------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------+
-| :ref:`sphx_glr_auto_examples_plot_fitting_mixed_model.py` (``plot_fitting_mixed_model.py``) | 00:00.000 | 0.0 MB |
-+-------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------+
-| :ref:`sphx_glr_auto_examples_plot_globalfits_local_and_global_parameters.py` (``plot_globalfits_local_and_global_parameters.py``) | 00:00.000 | 0.0 MB |
-+-------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------+
-| :ref:`sphx_glr_auto_examples_plot_multigauss_fitting_4pdeer.py` (``plot_multigauss_fitting_4pdeer.py``) | 00:00.000 | 0.0 MB |
-+-------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------+
-| :ref:`sphx_glr_auto_examples_plot_param_uncertainty_propagation.py` (``plot_param_uncertainty_propagation.py``) | 00:00.000 | 0.0 MB |
-+-------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------+
-| :ref:`sphx_glr_auto_examples_plot_pseudotitration_parameter_free.py` (``plot_pseudotitration_parameter_free.py``) | 00:00.000 | 0.0 MB |
-+-------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------+
diff --git a/docsrc/source/changelog.rst b/docsrc/source/changelog.rst
new file mode 100644
index 000000000..62aa99095
--- /dev/null
+++ b/docsrc/source/changelog.rst
@@ -0,0 +1,6 @@
+
+----------
+Changelog
+----------
+
+.. include:: ../../CHANGELOG.md
diff --git a/docsrc/source/download.rst b/docsrc/source/download.rst
deleted file mode 100644
index 4fbcc9fff..000000000
--- a/docsrc/source/download.rst
+++ /dev/null
@@ -1,53 +0,0 @@
-Download
-======================
-
-
-DeerLab is distributed in two different formats:
-
- - Releases
- Releases are the official packages of DeerLab containing the essentials for the full-functionality of the program. They contain:
-
- - All DeerLab functions
- - A compiled offline version of this web page and documentation
- - All tutorial scripts
-
- - Source code
- The source code contains all code used in the development of DeerLab, including:
-
- - All DeerLab functions
- - All source files for compiling the web page and documentation
- - The full test suite
- - All tutorial scripts
- - All build and CI scripts
- - No built documentation
-
-
------------------------
-
-
-Downloading Releases
------------------------
-
-All releases (including previous versions) are available in the official DeerLab `GitHub repository `_.
-
-1) From the main page, select the ``releases`` tab
-
- .. image:: ./images/downloads1.png
-
-2) Select the release you want to download
-
- .. image:: ./images/downloads2.png
-
-3) Download the ``DeerLab_x.y.zip`` file. Extract the files on your desired location and follow the Installation page instructions.
-
- .. image:: ./images/downloads3.png
-
-
-Downloading the source code
------------------------------
-
-The source code is easily available in the official DeerLab `GitHub repository `_ either by downloading or cloning the repository.
-
-1) From the main page, select the ``Clone or download`` tab
-
- .. image:: ./images/downloads4.png
diff --git a/docsrc/source/firstscript.rst b/docsrc/source/firstscript.rst
index 95cc8f084..6d72c2ff2 100644
--- a/docsrc/source/firstscript.rst
+++ b/docsrc/source/firstscript.rst
@@ -32,8 +32,8 @@ Next, we combine the distance distribution and the background into a full 4-puls
.. code-block:: python
- V = dipolarsignal(t,r,P,lam,B) # DEER signal
-
+ K = dipolarkernel(t,r,lam,B) # DEER kernel
+ V = K@P # DEER signal
sig = 0.01 # noise level
Vexp = V + whitegaussnoise(V,sig) # add noise
diff --git a/docsrc/source/functions.rst b/docsrc/source/functions.rst
index 6919472a5..f20a5e516 100644
--- a/docsrc/source/functions.rst
+++ b/docsrc/source/functions.rst
@@ -47,7 +47,6 @@ This class of functions can be used and/or combined to create fitting routines o
./functions/fitsignal
./functions/backgroundstart
- ./functions/fitbackground
./functions/fitmultimodel
./functions/fitparamodel
./functions/fitregmodel
@@ -157,7 +156,7 @@ Legacy Functions
=========================================
-This group of functions provides tools for reproducing analysis methods or workflows encountered in older software, particularly DeerAnalysis. These functions are not recommended for routine data analysis.
+This group of functions provides tools for reproducing analysis methods or workflows encountered in older software. These functions are not recommended for routine data analysis.
.. rst-class:: func-list
diff --git a/docsrc/source/index.rst b/docsrc/source/index.rst
index a349ea467..500376968 100644
--- a/docsrc/source/index.rst
+++ b/docsrc/source/index.rst
@@ -1,4 +1,4 @@
-DeerLab-development Documentation
+DeerLab 0.10.0 Documentation
=====================================================
.. warning:: DeerLab is currently in the pre-release stage (version numbers 0.x.x) and under active development. Major changes are likely before the first stable version (1.0.0) is released.
@@ -7,7 +7,7 @@ DeerLab is a free software package for the analysis of dipolar EPR (electron par
DeerLab consists of a collection of functions that perform modelling, processing or fitting tasks. They can be combined in scripts to build custom data analysis workflows. To model distance distributions, DeerLab supports two types of model classes and associated workflows: parameter-free models (as used in Tikhonov regularization) as well as a series of parameterized models (mutli-Gaussians etc). It also provides a selection of background and experiment models.
-When you use DeerLab in your work, please cite
+When you use DeerLab in your work, please cite the following publication
.. code-block:: text
@@ -49,7 +49,7 @@ When you use DeerLab in your work, please cite
:maxdepth: 1
./funding
-
+ ./changelog
.. Indices and tables
.. ==================
diff --git a/docsrc/source/installation.rst b/docsrc/source/installation.rst
index d8a1c1bdd..92b3296c2 100644
--- a/docsrc/source/installation.rst
+++ b/docsrc/source/installation.rst
@@ -11,7 +11,11 @@ DeerLab requires one of the following versions of the Python interpreter
which can be downloaded from the `official Python distribution `_.
-For Windows systems it is imporant to ensure that the **Install launcher for all users (recommended)** and the **Add Python 3.7 to PATH** checkboxes at the bottom are checked.
+For Windows systems it is imporant to ensure that the **Install launcher for all users (recommended)** and the **Add Python 3.x to PATH** checkboxes at the bottom are checked. To test if python has been succesfully installed, open a terminal window and run the command::
+
+ python
+
+wihch should open the Python interface as well as display the installed Python version. To exit use the ``exit()`` command.
Installing pre-built DeerLab
-----------------------------
@@ -33,6 +37,7 @@ DeerLab will install the following packages:
* `cvxopt `_ - Free software package for convex optimization
* `numpy `_ - Base N-dimensional array package
* `scipy `_ - Fundamental library for scientific computing
+ * `numdifftools `_ - Tools to solve automatic numerical differentiation problems in one or more variables.
The installed numerical packages (numpy, scipy, cvxopt) are linked against different BLAS libraries depending on the OS:
@@ -40,6 +45,9 @@ The installed numerical packages (numpy, scipy, cvxopt) are linked against diffe
* Linux: linked against OpenBLAS
* Mac: linked against BLAS/LAPACK from the Accelerate framework
+If an error occurs during or after the installation please consult `this section <./installation_failed.html>`_ for a possible solution.
+
+
Installing older versions
-------------------------
@@ -48,12 +56,12 @@ Any DeerLab >0.10.0 release can be installed via pip using the following command
python -m pip install deerlab==x.x.x
-Older DeerLab 0.9.x versions, written for MATLAB are available from an `archived repository `_. Download and installation instruction for the MATLAB environment are provided in the released documentation. MATLAB releases have been deprecated and no further support is provided.
+Older DeerLab 0.9.x versions, written for MATLAB are available from an `archived repository `_. Download and installation instruction for the MATLAB environment are provided in the released documentation. MATLAB releases have been deprecated and no further support is provided.
Installing from source
----------------------
-To install DeerLab from the source, first it must be downloaded or cloned from the `DeerLab repository `_. DeerLab and its dependencies can be installed by running the following command on a terminal window to install DeerLab as a static Python package::
+To install DeerLab from the source, first it must be downloaded or cloned from the `DeerLab repository `_. DeerLab and its dependencies can be installed by running the following command on a terminal window to install DeerLab as a static Python package::
python setup.py install
diff --git a/docsrc/source/installation_failed.rst b/docsrc/source/installation_failed.rst
new file mode 100644
index 000000000..bc70d1e8b
--- /dev/null
+++ b/docsrc/source/installation_failed.rst
@@ -0,0 +1,41 @@
+.. _installation_failed
+
+====================
+Installation failed
+====================
+
+Known Issues #1: DLL load failed
+--------------------------------
+
+
+On a **Windows** computer, if when trying to run a DeerLab function you the following message:
+
+.. code-block:: text
+
+ ImportError: DLL load failed: The specified module could not be found.
+
+This happens when the MKL libraries have not been properly linked in ``numpy``, ``scipy`` or ``cvxopt`` installations (typically ``numpy``). This can happen due to firewall restrictions, user rights, or internet connection issues during the DeerLab installation. To solve this the best solution is to manually install as follows.
+
+1) Access https://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy
+
+2) There download the appropiate ``numpy`` wheels file according to your installed Python version and Windows system:
+
+.. code-block:: text
+
+ Python version (3.x)
+ Package name | Windows architecture (32-64 bit)
+ | | |
+ v v v
+ numpy-1.19.1+mkl-cp36-cp36m-win_amd64.whl
+
+
+3) Once downloaded, open a terminal at the location of the ``.whl`` file and run the command:
+
+.. code-block:: text
+
+ python -m pip install "numpy-1.19.1+mkl-cp36-cp36m-win_amd64.whl"
+
+
+making sure that the name of the ``.whl`` file matches the one you have downloaded.
+
+This will install ``numpy`` and properly link all MKL DLL files. DeerLab can be used again. Should the error persists, repeat this process for the ``scipy`` and ``cvxopt`` packages (in that order).
\ No newline at end of file
diff --git a/examples/plot_fitting_4pdeer.py b/examples/plot_fitting_4pdeer.py
index bbda4bc77..99904f1b7 100644
--- a/examples/plot_fitting_4pdeer.py
+++ b/examples/plot_fitting_4pdeer.py
@@ -5,7 +5,7 @@
How to fit a simple 4-pulse DEER signal with a parameter-free distribution.
"""
-# %%
+
import numpy as np
import matplotlib.pyplot as plt
from deerlab import *
@@ -14,7 +14,6 @@
#Generate data
#--------------
-# %%
t = np.linspace(-0.1,4,250) # time axis, us
r = np.linspace(1.5,6,len(t)) # distance axis, ns
param = [3, 0.3, 0.2, 3.5, 0.3, 0.65, 3.8, 0.2, 0.15] # parameters for three-Gaussian model
@@ -29,9 +28,4 @@
# %% [markdown]
# Run fit
#---------
-
-# %%
fit = fitsignal(Vexp,t,r,'P',bg_hom3d,ex_4pdeer,display=True)
-plt.show()
-
-# %%
diff --git a/examples/plot_fitting_mixed_model.py b/examples/plot_fitting_mixed_model.py
index d591a7356..a4f1130f4 100644
--- a/examples/plot_fitting_mixed_model.py
+++ b/examples/plot_fitting_mixed_model.py
@@ -89,7 +89,7 @@
par0 = info['Start'] # built-in start values
lb = info['Lower'] # built-in lower bounds
ub = info['Upper'] # built-in upper bounds
-fit = fitparamodel(V,Vmodel,par0,lb,ub,MultiStart=10)
+fit = fitparamodel(V,Vmodel,par0,lb,ub,multistart=10)
fitpar = fit.param
# %% [markdown]
# From the fitted parameter set ``fitpar`` we can now generate our fitted distance
diff --git a/examples/plot_globalfits_local_and_global_parameters.py b/examples/plot_globalfits_local_and_global_parameters.py
index 19d3eeb77..70d7b6a7d 100644
--- a/examples/plot_globalfits_local_and_global_parameters.py
+++ b/examples/plot_globalfits_local_and_global_parameters.py
@@ -119,7 +119,7 @@ def myABmodel(par):
Vs = [V1,V2]
# Fit the global parametric model to both signals
-fit = fitparamodel(Vs,model,par0,lower,upper,MultiStart=40)
+fit = fitparamodel(Vs,model,par0,lower,upper,multistart=40)
# The use of the option 'multistart' will help the solver to find the
# global minimum and not to get stuck at local minima.
diff --git a/setup.py b/setup.py
index 11155afb4..fddc8e451 100644
--- a/setup.py
+++ b/setup.py
@@ -1,52 +1,75 @@
-from setuptools import setup, find_packages
+from setuptools import setup
from setuptools.command.install import install
from setuptools.command.develop import develop
import platform
import subprocess
+# Custom OS-specific installation script
def install_dependencies():
- subprocess.run(['pip','install','memoization'])
- subprocess.run(['pip','install','matplotlib'])
- subprocess.run(['pip','install','pytest'])
- # Dependencies with OS-specific BLAS
- if platform.system() is 'Windows':
- # Install Numpy,SciPy, CVXopt linked to MKL
- subprocess.run(['pip','install','pipwin'])
- subprocess.run(['pipwin','install','numpy'])
- subprocess.run(['pipwin','install','scipy'])
- subprocess.run(['pipwin','install','cvxopt'])
- else:
- # Install Numpy,SciPy, CVXopt linked to OpenBLAS
- subprocess.run(['pip','install','numpy'])
- subprocess.run(['pip','install','scipy'])
- subprocess.run(['pip','install','cvxopt'])
+ subprocess.run(['pip','install','memoization'],check=True)
+ subprocess.run(['pip','install','matplotlib'],check=True)
+ # Dependencies with OS-specific BLAS
+ if platform.system() is 'Windows':
+ # Install Numpy,SciPy, CVXopt linked to MKL
+ subprocess.run(['pip','install','pipwin'],check=True)
+ subprocess.run(['pipwin','install','numpy'],check=False)
+ subprocess.run(['pipwin','install','scipy'],check=False)
+ subprocess.run(['pipwin','install','cvxopt'],check=False)
+ else:
+ # Install Numpy,SciPy, CVXopt linked to OpenBLAS
+ subprocess.run(['pip','install','numpy'],check=True)
+ subprocess.run(['pip','install','scipy'],check=True)
+ subprocess.run(['pip','install','cvxopt'],check=True)
+ subprocess.run(['pip','install','numdifftools'],check=True)
class install_routine(install):
- """Customized setuptools install command"""
- def run(self):
- install.run(self)
- install_dependencies()
+ """Customized setuptools install command"""
+ def run(self):
+ install.run(self)
+ install_dependencies()
class develop_routine(develop):
- """Customized setuptools install command"""
- def run(self):
- develop.run(self)
- install_dependencies()
+ """Customized setuptools install command"""
+ def run(self):
+ develop.run(self)
+ install_dependencies()
+ subprocess.run(['pip','install','pytest'],check=True) # Install only on development version
+
setup(
name='DeerLab',
- version='0.10.0',
- author='Luis Fabregas, Stefan Stoll and other contributors',
+ version=open('VERSION').read().splitlines()[0],
+ author='Luis Fábregas Ibáñez , Stefan Stoll and other contributors',
package_dir={'deerlab': 'deerlab',
'deerlab.utils': 'deerlab/utils'},
packages=['deerlab','deerlab.utils'],
- url='https://jeschkelab.github.io/DeerLab/',
+ url='https://github.com/JeschkeLab/DeerLab',
+ project_urls = {
+ 'Documentation': 'https://jeschkelab.github.io/DeerLab/',
+ 'Source': 'https://github.com/JeschkeLab/DeerLab',
+ },
+ python_requires='>=3.6',
license='LICENSE.txt',
- description='',
+ include_package_data = True,
+ keywords='data analysis EPR spectroscopy DEER PELDOR',
+ description='Comprehensive package for data analysis of dipolar EPR spectroscopy',
long_description=open('README.md').read(),
+ long_description_content_type="text/markdown",
cmdclass={
'install': install_routine,
'develop': develop_routine
},
+ classifiers=[
+ 'Development Status :: 4 - Beta',
+ 'Intended Audience :: Science/Research',
+ 'License :: OSI Approved :: MIT License',
+ 'Operating System :: Microsoft :: Windows',
+ 'Operating System :: MacOS',
+ 'Operating System :: POSIX :: Linux',
+ 'Programming Language :: Python :: 3.6',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Topic :: Scientific/Engineering',
+ ]
)
\ No newline at end of file
diff --git a/test/test_correctphase.py b/test/test_correctphase.py
index 3272425f7..d4c70f601 100644
--- a/test/test_correctphase.py
+++ b/test/test_correctphase.py
@@ -1,8 +1,6 @@
import numpy as np
from numpy import pi
from deerlab import correctphase
-from deerlab.dd_models import dd_gauss,dd_gauss2
-from deerlab.bg_models import bg_exp
def test_basics():
@@ -52,7 +50,7 @@ def test_fit_imag_offset():
ImOffsetIn = 40j
Vphased = V*np.exp(1j*phiIn) + ImOffsetIn
- _,_,_,ImOffsetOut = correctphase(Vphased,[],fitImagOffset=True,full_output=True)
+ _,_,_,ImOffsetOut = correctphase(Vphased,[],imagoffset=True,full_output=True)
assert abs(ImOffsetIn - ImOffsetOut) < 1e-4
#============================================================
@@ -62,7 +60,7 @@ def test_multiple_datasets():
#============================================================
"Check that the phase correcion works when passing multiple datasets"
- V = np.matlib.repmat(np.arange(100),20,1).T
+ V = np.tile(np.arange(100),(20,1)).T
phases = np.mod(np.linspace(-3*pi/4,pi/2,20),pi)
Vphased = V*np.exp(1j*phases)
@@ -76,7 +74,7 @@ def test_multiple_datasets_manual():
#============================================================
"Check that manual phase correcion works when passing multiple datasets"
- V = np.matlib.repmat(np.arange(100),20,1).T
+ V = np.tile(np.arange(100),(20,1)).T
phases = np.mod(np.linspace(-3*pi/4,pi/2,20),pi)
Vphased = V*np.exp(1j*phases)
diff --git a/test/test_correctzerotime.py b/test/test_correctzerotime.py
index d2806d613..3ba01aca0 100644
--- a/test/test_correctzerotime.py
+++ b/test/test_correctzerotime.py
@@ -1,9 +1,6 @@
import numpy as np
-from numpy import pi, inf, NaN
from deerlab import correctzerotime
-from deerlab.dd_models import dd_gauss,dd_gauss3
-from deerlab.utils import ovl
def test_correction():
#=======================================================================
diff --git a/test/test_dipolarbackground.py b/test/test_dipolarbackground.py
index bdc1db175..fd0e02074 100644
--- a/test/test_dipolarbackground.py
+++ b/test/test_dipolarbackground.py
@@ -1,6 +1,6 @@
import numpy as np
-from deerlab.bg_models import *
+from deerlab.bg_models import bg_exp
from deerlab.dipolarbackground import dipolarbackground
diff --git a/test/test_dipolarkernel.py b/test/test_dipolarkernel.py
index 8ccd20250..21415ab2a 100644
--- a/test/test_dipolarkernel.py
+++ b/test/test_dipolarkernel.py
@@ -4,7 +4,6 @@
from deerlab.bg_models import bg_exp
from deerlab.dd_models import dd_gauss
from deerlab.dipolarkernel import dipolarkernel,calckernelmatrix
-from deerlab.dipolarbackground import dipolarbackground
ge = 2.00231930436256 # free-electron g factor
diff --git a/test/test_fitmultimodel.py b/test/test_fitmultimodel.py
index 44b0485fc..3fcb66311 100644
--- a/test/test_fitmultimodel.py
+++ b/test/test_fitmultimodel.py
@@ -81,8 +81,8 @@ def test_rescaling():
scale = 1e3
V = K@P
- fit1 = fitmultimodel(V*scale,K,r,dd_gauss,3,'aic',normP=True,uqanalysis=False)
- fit2 = fitmultimodel(V,K,r,dd_gauss,3,'aic',normP=False,uqanalysis=False)
+ fit1 = fitmultimodel(V*scale,K,r,dd_gauss,3,'aic',renormalize=True,uqanalysis=False)
+ fit2 = fitmultimodel(V,K,r,dd_gauss,3,'aic',renormalize=False,uqanalysis=False)
assert max(abs(fit1.P - fit2.P)) < 1e-4
#=======================================================================
diff --git a/test/test_fitparamodel.py b/test/test_fitparamodel.py
index 9c9e34e49..9bb22869d 100644
--- a/test/test_fitparamodel.py
+++ b/test/test_fitparamodel.py
@@ -1,9 +1,7 @@
import numpy as np
-from numpy import pi, inf, NaN
from deerlab import dipolarkernel, whitegaussnoise, fitparamodel
from deerlab.dd_models import dd_gauss, dd_rice
-from deerlab.utils import ovl
def test_gaussian():
@@ -141,7 +139,6 @@ def test_confinter_Pfit():
assert_confidence_intervals(paruq.ci(50),paruq.ci(95),parfit,lb,ub)
# ======================================================================
-
def test_manual_covmatrix():
# ======================================================================
"Check that covariance matrix can be manually specified"
diff --git a/test/test_fitregmodel.py b/test/test_fitregmodel.py
index 802b46213..c12ad184b 100644
--- a/test/test_fitregmodel.py
+++ b/test/test_fitregmodel.py
@@ -1,7 +1,6 @@
import numpy as np
-from numpy import pi, inf, NaN
-from deerlab import fitregmodel,dipolarkernel, regoperator, regparamrange, selregparam, whitegaussnoise
+from deerlab import fitregmodel,dipolarkernel, regoperator, whitegaussnoise
from deerlab.dd_models import dd_gauss,dd_gauss2
from deerlab.utils import ovl
@@ -271,7 +270,7 @@ def test_scale_agnostic():
fit = fitregmodel(V,K,r,'tikhonov','aic',renormalize = False)
- assert max(abs(P - fit.P/scale)) < 1e-4
+ assert max(abs(P - fit.P/scale)) < 1e-3
#============================================================
def test_scale_fit():
diff --git a/test/test_fitsignal.py b/test/test_fitsignal.py
index c61de1b46..9f8fb67ec 100644
--- a/test/test_fitsignal.py
+++ b/test/test_fitsignal.py
@@ -1,8 +1,8 @@
import numpy as np
-from numpy import pi, inf, NaN
+from numpy import inf
from deerlab import dipolarkernel, whitegaussnoise, fitsignal
-from deerlab.dd_models import dd_gauss, dd_rice
+from deerlab.dd_models import dd_gauss
from deerlab.bg_models import bg_exp
from deerlab.ex_models import ex_4pdeer, ex_5pdeer, ex_7pdeer, ex_ovl4pdeer
from deerlab.utils import ovl
@@ -34,7 +34,6 @@ def test_4pdeer():
assert_experiment_model(ex_4pdeer)
# ======================================================================
-test_4pdeer()
def test_5pdeer():
# ======================================================================
@@ -157,6 +156,7 @@ def test_boundaries():
def test_global_4pdeer():
# ======================================================================
"Check the correct fit of two 4-DEER signals"
+
r = np.linspace(2,6,90)
P = dd_gauss(r,[4.5, 0.6])
@@ -272,6 +272,7 @@ def assert_confinter_param(subset):
Bmodel = lambda t,lam: bgmodel(t,kappa,lam)
t = np.linspace(0,5,100)
+ np.random.seed(0)
V = dipolarkernel(t,r,pathinfo,Bmodel)@P + whitegaussnoise(t,0.01)
fit = fitsignal(V,t,r,ddmodel,bgmodel,exmodel,uqanalysis=True)
@@ -337,6 +338,7 @@ def assert_confinter_models(subset):
Bmodel = lambda t,lam: bgmodel(t,kappa,lam)
t = np.linspace(0,5,100)
+ np.random.seed(0)
V = dipolarkernel(t,r,pathinfo,Bmodel)@P + whitegaussnoise(t,0.03)
fit = fitsignal(V,t,r,ddmodel,bgmodel,exmodel,uqanalysis=True)
@@ -365,28 +367,79 @@ def assert_confinter_models(subset):
def test_confinter_Pfit():
# ======================================================================
- "Check that the confidence inervals for fitted parametric distribution is correct"
+ "Check that the confidence inervals for fitted parametric distribution are correct"
assert_confinter_models('Pfit')
# ======================================================================
def test_confinter_Pfitfree():
# ======================================================================
- "Check that the confidence inervals for fitted distribution is correct"
+ "Check that the confidence inervals for fitted distribution are correct"
assert_confinter_models('Pfitfree')
# ======================================================================
def test_confinter_Vfit():
# ======================================================================
- "Check that the confidence inervals for fitted distribution is correct"
+ "Check that the confidence inervals for fitted distribution are correct"
assert_confinter_models('Vfit')
# ======================================================================
def test_confinter_Bfit():
# ======================================================================
- "Check that the confidence inervals for fitted distribution is correct"
+ "Check that the confidence inervals for fitted distribution are correct"
assert_confinter_models('Bfit')
# ======================================================================
+def assert_confinter_noforeground():
+# ======================================================================
+ "Check that the confidence inervals for a pure background fit are correct"
+
+ bgmodel = bg_exp
+ t = np.linspace(0,5,100)
+ r = np.linspace(2,6,90)
+ P = dd_gauss(r,[4.5, 0.6])
+
+ kappa = 0.4
+ lam = 0.3
+ Bmodel = bgmodel(t,kappa,lam)
+
+ np.random.seed(0)
+ V = dipolarkernel(t,r,lam,Bmodel)@P + whitegaussnoise(t,0.01)
+
+ fit = fitsignal(V,t,r,None,bgmodel,ex_4pdeer,uqanalysis=True)
+
+ Bfit = fit.B
+ Buq = fit.Buncert
+ Bci50 = Buq.ci(50)
+ Bci95 = Buq.ci(95)
+ lb = np.full_like(t,-inf)
+ ub = np.full_like(t,inf)
+
+ assert_confidence_intervals(Bci50,Bci95,Bfit,lb,ub)
+# ======================================================================
+
+def assert_confinter_dipevofun():
+# ======================================================================
+ "Check that the confidence inervals for a dipolar evolution function fit are correct"
+
+ r = np.linspace(2,6,90)
+ P = dd_gauss(r,[4.5, 0.6])
+
+ t = np.linspace(0,5,100)
+ np.random.seed(0)
+ V = dipolarkernel(t,r)@P + whitegaussnoise(t,0.01)
+
+ fit = fitsignal(V,t,r,'P',None,None,uqanalysis=True)
+
+ Pfit = fit.P
+ Puq = fit.Puncert
+ Pci50 = Puq.ci(50)
+ Pci95 = Puq.ci(95)
+ lb = np.zeros_like(r,0)
+ ub = np.full_like(r,inf)
+
+ assert_confidence_intervals(Pci50,Pci95,Pfit,lb,ub)
+# ======================================================================
+
def test_global_scale_4pdeer():
# ======================================================================
"Check the correct fit of two 4-DEER signals"
diff --git a/test/test_mixmodels.py b/test/test_mixmodels.py
index 36b333dcd..79fef20ec 100644
--- a/test/test_mixmodels.py
+++ b/test/test_mixmodels.py
@@ -1,12 +1,11 @@
import numpy as np
-from deerlab import mixmodels, dipolarkernel, fitparamodel
+from deerlab import mixmodels
from deerlab.dd_models import dd_gauss, dd_rice
def test_gaussgauss():
# ======================================================================
"Check the construction of a mixed model of Gaussian-Gaussian"
- t = np.linspace(0,3,200)
r = np.linspace(2,6,100)
parIn1 = [3, 0.5]
P1 = dd_gauss(r,parIn1)
@@ -26,7 +25,6 @@ def test_gaussrice():
# ======================================================================
"Check the construction of a mixed model of Gaussian-Gaussian"
- t = np.linspace(0,3,200)
r = np.linspace(2,6,100)
parIn1 = [3, 0.5]
P1 = dd_gauss(r,parIn1)
diff --git a/test/test_nnls.py b/test/test_nnls.py
index 46ff6767e..a45491328 100644
--- a/test/test_nnls.py
+++ b/test/test_nnls.py
@@ -1,7 +1,6 @@
import numpy as np
-from numpy import pi, inf, NaN
from deerlab.nnls import fnnls, cvxnnls, nnlsbpp
-from deerlab import lsqcomponents, dipolarkernel, regoperator, whitegaussnoise
+from deerlab import lsqcomponents, dipolarkernel, regoperator
from deerlab.dd_models import dd_gauss,dd_gauss2
diff --git a/test/test_noiselevel.py b/test/test_noiselevel.py
index 9651843c8..8b876308c 100644
--- a/test/test_noiselevel.py
+++ b/test/test_noiselevel.py
@@ -1,6 +1,6 @@
import numpy as np
from deerlab import noiselevel, whitegaussnoise, dipolarkernel
-from deerlab.dd_models import dd_gauss,dd_gauss2
+from deerlab.dd_models import dd_gauss
from deerlab.bg_models import bg_exp
diff --git a/test/test_regoperator.py b/test/test_regoperator.py
index df6561a35..8a437eae4 100644
--- a/test/test_regoperator.py
+++ b/test/test_regoperator.py
@@ -1,6 +1,6 @@
import numpy as np
-from numpy import pi, inf, NaN
+from numpy import pi
from deerlab import regoperator
def test_L0shape():
diff --git a/test/test_regparamrange.py b/test/test_regparamrange.py
index e0279ef64..ff1024c03 100644
--- a/test/test_regparamrange.py
+++ b/test/test_regparamrange.py
@@ -1,6 +1,5 @@
import numpy as np
-from numpy import pi, inf, NaN
from deerlab import dipolarkernel, regoperator, regparamrange
def test_resolution():
diff --git a/test/test_selregparam.py b/test/test_selregparam.py
index 92eb88afc..690d5bf8c 100644
--- a/test/test_selregparam.py
+++ b/test/test_selregparam.py
@@ -1,6 +1,5 @@
import numpy as np
-from numpy import pi, inf, NaN
from deerlab import dipolarkernel, regoperator, regparamrange, selregparam, whitegaussnoise
from deerlab.dd_models import dd_gauss,dd_gauss2
@@ -154,7 +153,7 @@ def test_gml_value():
loga = get_alpha_from_method('gml')
logaref = -7.89 # Computed with DeerLab-Matlab (0.9.2)
- assert abs(1-loga/logaref) < 0.15
+ assert abs(1-loga/logaref) < 0.16
#=======================================================================
def test_lr_value():
diff --git a/test/test_snlls.py b/test/test_snlls.py
index ea7b94598..3d60a3f3f 100644
--- a/test/test_snlls.py
+++ b/test/test_snlls.py
@@ -331,7 +331,7 @@ def assert_reg_type(regtype):
fit = snlls(V,lambda lam: dipolarkernel(t,r,lam),nlpar0,lb,ub,lbl,ubl,regtype = regtype, uqanalysis=False)
Pfit = fit.lin
- assert np.max(abs(P - Pfit)) < 2e-2
+ assert np.max(abs(P - Pfit)) < 4e-2
def test_reg_tikh():
#=======================================================================