diff --git a/.github/workflows/ci_PR.yml b/.github/workflows/ci_PR.yml index 0e0e7d8f..44f9b528 100644 --- a/.github/workflows/ci_PR.yml +++ b/.github/workflows/ci_PR.yml @@ -15,23 +15,18 @@ jobs: steps: - uses: actions/checkout@v3 - + - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v3 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - - - name: Install dependencies - run: | + cache: 'pip' + cache-dependency-path: setup.py + - run: | python -m pip install --upgrade pip pip install wheel pip install . - - - name: Windows MKL linking - if: matrix.os == 'windows-latest' - run: | - python upgrade_mkl.py - + - name: Test with pytest run: | pytest diff --git a/.github/workflows/ci_scheduled.yml b/.github/workflows/ci_scheduled.yml index a32f8caa..5c94e264 100644 --- a/.github/workflows/ci_scheduled.yml +++ b/.github/workflows/ci_scheduled.yml @@ -14,51 +14,57 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] python-version: [3.8, 3.9, "3.10", "3.11"] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} + cache: 'pip' + cache-dependency-path: setup.py + - run: | + python -m pip install --upgrade pip + pip install wheel + pip install . - - uses: actions/cache@v2 - if: startsWith(runner.os, 'Windows') - with: - path: | - ~\AppData\Local\pip\Cache - key: ${{ runner.os }}-${{ hashFiles('**/setup.py') }} - restore-keys: | - {{ runner.os }}-pip- +# - uses: actions/cache@v2 +# if: startsWith(runner.os, 'Windows') +# with: +# path: | +# ~\AppData\Local\pip\Cache +# key: ${{ runner.os }}-${{ hashFiles('**/setup.py') }} +# restore-keys: | +# {{ runner.os }}-pip- - - uses: actions/cache@v2 - if: startsWith(runner.os, 'macOS') - with: - path: | - ~/Library/Caches/pip - key: ${{ runner.os }}-${{ hashFiles('**/setup.py') }} - restore-keys: | - {{ runner.os }}-pip- +# - uses: actions/cache@v2 +# if: startsWith(runner.os, 'macOS') +# with: +# path: | +# ~/Library/Caches/pip +# key: ${{ runner.os }}-${{ hashFiles('**/setup.py') }} +# restore-keys: | +# {{ runner.os }}-pip- - - uses: actions/cache@v2 - if: startsWith(runner.os, 'Linux') - with: - path: | - ~/.cache/pip - key: ${{ runner.os }}-${{ hashFiles('**/setup.py') }} - restore-keys: | - {{ runner.os }}-pip- +# - uses: actions/cache@v2 +# if: startsWith(runner.os, 'Linux') +# with: +# path: | +# ~/.cache/pip +# key: ${{ runner.os }}-${{ hashFiles('**/setup.py') }} +# restore-keys: | +# {{ runner.os }}-pip- - - name: Install dependencies - if: steps.cache.outputs.cache-hit != 'false' - run: | - python -m pip install --upgrade pip - pip install wheel - pip install . +# - name: Install dependencies +# if: steps.cache.outputs.cache-hit != 'false' +# run: | +# python -m pip install --upgrade pip +# pip install wheel +# pip install . - - name: Windows MKL linking - if: matrix.os == 'windows-latest' - run: | - python upgrade_mkl.py +# - name: Windows MKL linking +# if: matrix.os == 'windows-latest' +# run: | +# python upgrade_mkl.py - name: Test with pytest run: pytest diff --git a/deerlab/classes.py b/deerlab/classes.py index 02dea71b..ca24870f 100644 --- a/deerlab/classes.py +++ b/deerlab/classes.py @@ -650,7 +650,6 @@ def propagate(self,model,lb=None,ub=None,samples=None): # Get the parameter uncertainty distribution values,pdf = self.pardist(n) # Random sampling form the uncertainty distribution - np.random.seed(0) sampled_parameters[n] = [np.random.choice(values, p=pdf/sum(pdf)) for _ in range(Nsamples)] # Convert to matrix sampled_parameters = np.atleast_2d(sampled_parameters) diff --git a/deerlab/dipolarkernel.py b/deerlab/dipolarkernel.py index b5c57ba7..5732e7f1 100644 --- a/deerlab/dipolarkernel.py +++ b/deerlab/dipolarkernel.py @@ -165,7 +165,7 @@ def dipolarkernel(t, r, *, pathways=None, mod=None, bg=None, method='fresnel', e The vector ``tinterp`` must cover all possible time shifts of the original ``t`` by the different refocusing times of the dipolar pathways. Returns - -------- + ------- K : ndarray Dipolar kernel matrix. diff --git a/deerlab/dipolarmodel.py b/deerlab/dipolarmodel.py index bb4b99d8..e5cc3e52 100644 --- a/deerlab/dipolarmodel.py +++ b/deerlab/dipolarmodel.py @@ -318,7 +318,6 @@ def dipolarpathways(*param): #----------------------------------------------------------------------- def _Pmultivar(param): rmeans,cholesky_factors = param[:Q], param[Q:] - np.random.seed(seed=1) Σ = choleskycovmat(Q,cholesky_factors) Pmultivar = multivariate_normal(rmeans, cov=Σ) return Pmultivar @@ -470,7 +469,6 @@ def Vmultispin_nonlinear_fcn(*nonlin): # Sample from the multi-variate distance distribution Nsamples = 1000000 - np.random.seed(seed=1) rsamples = Pmodel.nonlinmodel(nonlin[Psubset]).rvs(Nsamples) rsamples = np.maximum(rsamples,1e-16) # Avoid values exactly at zero diff --git a/docsrc/source/dipolar_guide_modelling.rst b/docsrc/source/dipolar_guide_modeling.rst similarity index 100% rename from docsrc/source/dipolar_guide_modelling.rst rename to docsrc/source/dipolar_guide_modeling.rst diff --git a/examples/basic_simulations/ex_simulate_4pdeer.py b/examples/basic_simulations/ex_simulate_4pdeer.py index 10b15260..ab6558b9 100644 --- a/examples/basic_simulations/ex_simulate_4pdeer.py +++ b/examples/basic_simulations/ex_simulate_4pdeer.py @@ -37,9 +37,8 @@ # Experiment model experiment = dl.ex_4pdeer(tau1,tau2, pathways=[1,2,3]) -reftime1 = experiment.reftimes[0] -reftime2 = experiment.reftimes[1] -reftime3 = experiment.reftimes[2] +reftime1, reftime2, reftime3 = experiment.reftimes(tau1,tau2) + # Construct the dipolar signal model Vmodel = dl.dipolarmodel(t,r,Pmodel=dl.dd_gauss, experiment=experiment) diff --git a/examples/basic_simulations/ex_simulate_5pdeer.py b/examples/basic_simulations/ex_simulate_5pdeer.py index 1b1ae132..e5d4ce91 100644 --- a/examples/basic_simulations/ex_simulate_5pdeer.py +++ b/examples/basic_simulations/ex_simulate_5pdeer.py @@ -37,8 +37,7 @@ r = np.arange(rmin,rmax,Δr) experiment = dl.ex_rev5pdeer(tau1,tau2,tau3, pathways=[1,2]) -reftime1 = experiment.reftimes[0] -reftime2 = experiment.reftimes[1] +reftime1, reftime2 = experiment.reftimes(tau1,tau2,tau3) # Construct the dipolar signal model Vmodel = dl.dipolarmodel(t,r,Pmodel=dl.dd_gauss, experiment=experiment) diff --git a/setup.py b/setup.py index 6c541f55..f7934a11 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ 'Documentation': 'https://jeschkelab.github.io/DeerLab/', 'Source': 'https://github.com/JeschkeLab/DeerLab', }, - python_requires='>=3.8', + python_requires='>=3.8,<3.11', license='LICENSE.txt', include_package_data = True, keywords='data analysis modeling least-squares EPR spectroscopy DEER PELDOR'.split(), @@ -22,7 +22,7 @@ 'numpy>=1.22.4', 'cvxopt>=1.0.0', 'scipy>=1.6.3', - 'joblib>-1.0.0', + 'joblib>=1.0.0', 'dill>=0.3.0', 'tqdm>=4.51.0', 'matplotlib>=3.3.4', @@ -44,4 +44,4 @@ 'Programming Language :: Python :: 3.10', 'Topic :: Scientific/Engineering', ] -) \ No newline at end of file +) diff --git a/test/test_selregparam.py b/test/test_selregparam.py index 910a57a5..75aa20c2 100644 --- a/test/test_selregparam.py +++ b/test/test_selregparam.py @@ -4,31 +4,31 @@ from deerlab import dipolarkernel, regoperator, selregparam, whitegaussnoise from deerlab.dd_models import dd_gauss,dd_gauss2 from deerlab.utils import assert_docstring -from deerlab.solvers import cvxnnls +from deerlab.solvers import qpnnls def test_compensate_condition(): #======================================================================= "Check that alpha compensates for larger condition numbers" r = np.linspace(2,6,100) - P = dd_gauss(r,3,0.2) + P = dd_gauss(r,3,0.16986436005760383) # Lower condition number t1 = np.linspace(0,3,200) K1 = dipolarkernel(t1,r) V1 = K1@P - alpha1 = selregparam(V1,K1,cvxnnls,method='aic') + alpha1 = selregparam(V1,K1,qpnnls,method='aic') # Larger condition number t2 = np.linspace(0,3,400) K2 = dipolarkernel(t2,r) V2 = K2@P - alpha2 = selregparam(V2,K2,cvxnnls,method='aic') + alpha2 = selregparam(V2,K2,qpnnls,method='aic') assert alpha2 > alpha1 #======================================================================= -def get_alpha_from_method(method): +def get_alpha_from_method(method, bounds=[1e-10,1e-6]): t = np.linspace(0,5,500) r = np.linspace(2,5,80) @@ -37,7 +37,7 @@ def get_alpha_from_method(method): L = regoperator(r,2,includeedges=True) V = K@P - alpha = selregparam(V,K,cvxnnls,method=method,noiselvl=0,regop=L) + alpha = selregparam(V,K,qpnnls,method=method,searchrange=bounds, noiselvl=0,regop=L) return np.log10(alpha) def test_aic_value(): @@ -45,7 +45,7 @@ def test_aic_value(): "Check that the value returned by the AIC selection method is correct" loga = get_alpha_from_method('aic') - logaref = -6.8108 # Computed with DeerLab (0.11.0) + logaref = -8.37288 # Computed with DeerLab (1.0) grid method using quadprog assert abs(1-loga/logaref) < 0.1 #======================================================================= @@ -55,7 +55,7 @@ def test_bic_value(): "Check that the value returned by the BIC selection method is correct" loga = get_alpha_from_method('bic') - logaref = -6.8089 # Computed with DeerLab (0.11.0) + logaref = -8.37288 # Computed with DeerLab (1.0) grid method using quadprog assert abs(1-loga/logaref) < 0.1 #======================================================================= @@ -65,7 +65,7 @@ def test_aicc_value(): "Check that the value returned by the AICc selection method is correct" loga = get_alpha_from_method('aicc') - logaref = -6.8075 # Computed with DeerLab (0.11.0) + logaref = -8.37288 # Computed with DeerLab (1.0) grid method using quadprog assert abs(1-loga/logaref) < 0.1 #======================================================================= @@ -75,7 +75,7 @@ def test_cv_value(): "Check that the value returned by the CV selection method is correct" loga = get_alpha_from_method('cv') - logaref = -5.8777 # Computed with DeerLab-Matlab (0.9.2) + logaref = -8.37288 # Computed with DeerLab (1.0) grid method using quadprog assert abs(1-loga/logaref) < 0.16 #======================================================================= @@ -85,7 +85,7 @@ def test_gcv_value(): "Check that the value returned by the GCV selection method is correct" loga = get_alpha_from_method('gcv') - logaref = -5.8778 # Computed with DeerLab-Matlab (0.9.2) + logaref = -8.37288 # Computed with DeerLab (1.0) grid method using quadprog assert abs(1-loga/logaref) < 0.16 #======================================================================= @@ -95,7 +95,7 @@ def test_rgcv_value(): "Check that the value returned by the rGCV selection method is correct" loga = get_alpha_from_method('rgcv') - logaref = -5.8778 # Computed with DeerLab-Matlab (0.9.2) + logaref = -8.37288 # Computed with DeerLab (1.0) grid method using quadprog assert abs(1-loga/logaref) < 0.16 #======================================================================= @@ -105,7 +105,7 @@ def test_srgcv_value(): "Check that the value returned by the srGCV selection method is correct" loga = get_alpha_from_method('srgcv') - logaref = -5.8771 # Computed with DeerLab-Matlab (0.9.2) + logaref = -8.16949 # Computed with DeerLab (1.0) grid method using quadprog assert abs(1-loga/logaref) < 0.17 #======================================================================= @@ -115,7 +115,7 @@ def test_rm_value(): "Check that the value returned by the RM selection method is correct" loga = get_alpha_from_method('rm') - logaref = -5.8785 # Computed with DeerLab-Matlab (0.9.2) + logaref = -8.28318 # Computed with DeerLab (1.0) brent method using quadprog assert abs(1-loga/logaref) < 0.2 #======================================================================= @@ -125,7 +125,7 @@ def test_ee_value(): "Check that the value returned by the EE selection method is correct" loga = get_alpha_from_method('ee') - logaref = -5.8798 # Computed with DeerLab-Matlab (0.9.2) + logaref = -8.37288 # Computed with DeerLab (1.0) grid method using quadprog assert abs(1-loga/logaref) < 0.2 #======================================================================= @@ -135,9 +135,9 @@ def test_ncp_value(): "Check that the value returned by the NCP selection method is correct" loga = get_alpha_from_method('ncp') - logaref = 1.7574 # Computed with DeerLab-Matlab (0.9.2) + logaref = -9.18644 # Computed with DeerLab (1.0) grid method using quadprog - assert abs(1-loga/logaref) < 0.1 + assert abs(1-loga/logaref) < 0.2 #======================================================================= def test_mcl_value(): @@ -145,7 +145,7 @@ def test_mcl_value(): "Check that the value returned by the MCL selection method is correct" loga = get_alpha_from_method('mcl') - logaref = -5.878 # Computed with DeerLab-Matlab (0.9.2) + logaref = -8.37288 # Computed with DeerLab (1.0) grid method using quadprog assert abs(1-loga/logaref) < 0.16 #======================================================================= @@ -155,7 +155,7 @@ def test_gml_value(): "Check that the value returned by the GML selection method is correct" loga = get_alpha_from_method('gml') - logaref = -7.89 # Computed with DeerLab-Matlab (0.9.2) + logaref = -9.267 # Computed with DeerLab (1.0) brent method using quadprog assert abs(1-loga/logaref) < 0.16 #======================================================================= @@ -165,7 +165,7 @@ def test_lr_value(): "Check that the value returned by the LR selection method is correct" loga = get_alpha_from_method('lr') - logaref = -7.66 # Computed with DeerLab (0.11.0) + logaref = -8.37288 # Computed with DeerLab (1.0) grid method using quadprog assert abs(1-loga/logaref) < 0.15 #======================================================================= @@ -175,7 +175,7 @@ def test_lc_value(): "Check that the value returned by the LC selection method is correct" loga = get_alpha_from_method('lc') - logaref = -1.39 + logaref = -8.37288 # Computed with DeerLab (1.0) grid method using quadprog assert abs(1-loga/logaref) < 0.20 #======================================================================= @@ -191,8 +191,8 @@ def test_algorithms(): L = regoperator(r,2) V = K@P + whitegaussnoise(t,0.02,seed=1) - alpha_grid = selregparam(V,K,cvxnnls,method='aic',algorithm='grid',regop=L) - alpha_brent = selregparam(V,K,cvxnnls,method='aic',algorithm='brent',regop=L) + alpha_grid = selregparam(V,K,qpnnls,method='aic',algorithm='grid',regop=L) + alpha_brent = selregparam(V,K,qpnnls,method='aic',algorithm='brent',regop=L) assert abs(1-alpha_grid/alpha_brent) < 0.15 #======================================================================= @@ -209,7 +209,7 @@ def test_nonuniform_r(): L = regoperator(r,2) V = K@P - logalpha = np.log10(selregparam(V,K,cvxnnls,method='aic',regop=L)) + logalpha = np.log10(selregparam(V,K,qpnnls,method='aic',regop=L)) logalpharef = -6.8517 assert abs(1 - logalpha/logalpharef) < 0.2 @@ -224,7 +224,7 @@ def assert_full_output(method): L = regoperator(r,2) V = K@P - alpha,alphas_evaled,functional,residuals,penalties = selregparam(V,K,cvxnnls,method='aic',algorithm=method,full_output=True,regop=L) + alpha,alphas_evaled,functional,residuals,penalties = selregparam(V,K,qpnnls,method='aic',algorithm=method,full_output=True,regop=L) errors = [] if np.size(alpha)!=1: errors.append("alphaopt is not a scalar") @@ -279,8 +279,8 @@ def test_manual_candidates(): alphas = np.linspace(-8,2,60) V = K@P - alpha_manual = np.log10(selregparam(V,K,cvxnnls,method='aic',candidates=alphas,regop=L)) - alpha_auto = np.log10(selregparam(V,K,cvxnnls,method='aic',regop=L)) + alpha_manual = np.log10(selregparam(V,K,qpnnls,method='aic',candidates=alphas,regop=L)) + alpha_auto = np.log10(selregparam(V,K,qpnnls,method='aic',regop=L)) assert abs(alpha_manual-alpha_auto)<1e-4 #======================================================================= @@ -297,7 +297,7 @@ def test_tikh_value(): V = K@P + whitegaussnoise(t,0.01) L = regoperator(r,2,includeedges=True) - alpha = selregparam(V,K,cvxnnls,method='aic',regop=L) + alpha = selregparam(V,K,qpnnls,method='aic',regop=L) loga = np.log10(alpha) logaref = -3.51 # Computed with DeerLab-Matlab (0.9.2) diff --git a/test/test_snlls.py b/test/test_snlls.py index 204b8404..c4618c16 100644 --- a/test/test_snlls.py +++ b/test/test_snlls.py @@ -287,11 +287,11 @@ def assert_solver(solver): assert ovl(P,Pfit) > 0.95 -def test_nnls_cvx(): +def test_nnls_qp(): #======================================================================= "Check that the 'cvx' algorithm used for the NNLS subproblem work" - assert_solver(solver='cvx') + assert_solver(solver='qp') #======================================================================= def test_nnls_fnnls():