Skip to content

Commit

Permalink
Release v0.10.0
Browse files Browse the repository at this point in the history
  • Loading branch information
luisfabib authored Aug 7, 2020
2 parents 0a0a933 + 49be4a2 commit 74edc63
Show file tree
Hide file tree
Showing 145 changed files with 484 additions and 6,024 deletions.
34 changes: 34 additions & 0 deletions .github/ISSUE_TEMPLATE/---bug-report.md
Original file line number Diff line number Diff line change
@@ -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.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
51 changes: 51 additions & 0 deletions .github/workflows/deploy_ghpages.yml
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ docsrc/__pycache__/
dist/
build/
.debugging.py
multidocs/**/*
docsrc/source/auto_examples/**/*
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.

-------------------------------
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -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
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include VERSION
46 changes: 44 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,45 @@
# PyDeerLab
<p align="center">
<img src="https://raw.githubusercontent.com/JeschkeLab/DeerLab/master/docsrc/source/_static/logo_dark.png" alt="DeerLab Logo" width="40%"></img>
</p>
</div>

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).
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.10.0-dev
v0.10.0
2 changes: 1 addition & 1 deletion deerlab/bootan.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):

Expand Down
4 changes: 2 additions & 2 deletions deerlab/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
32 changes: 16 additions & 16 deletions deerlab/correctphase.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand All @@ -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
Expand All @@ -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:
Expand All @@ -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

Expand Down
2 changes: 1 addition & 1 deletion deerlab/fftspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
"""

Expand Down
Loading

0 comments on commit 74edc63

Please sign in to comment.