From f61366b62098ebe383154cd0f7302d1787135c2b Mon Sep 17 00:00:00 2001 From: Jochem Smit Date: Sun, 15 Nov 2020 16:08:10 +0100 Subject: [PATCH] removed expfact files and api --- AUTHORS.rst | 9 +- README.rst | 9 +- comparisons/Rate differences histograms.png | Bin 17503 -> 0 bytes comparisons/Rate differences.png | Bin 54840 -> 0 bytes comparisons/comparison.py | 37 ------ comparisons/random_sequences.py | 48 ------- examples.rst | 20 --- hdxrate/expfact/__init__.py | 0 hdxrate/expfact/api.py | 64 --------- hdxrate/expfact/constants.py | 103 -------------- hdxrate/expfact/kint.py | 140 -------------------- hdxrate/hdxrate.py | 14 +- hdxrate/psx/IntrinsicExchange.py | 14 -- hdxrate/psx/api.py | 2 - tests/test_hdxrate.py | 4 - 15 files changed, 7 insertions(+), 457 deletions(-) delete mode 100644 comparisons/Rate differences histograms.png delete mode 100644 comparisons/Rate differences.png delete mode 100644 comparisons/comparison.py delete mode 100644 comparisons/random_sequences.py delete mode 100644 examples.rst delete mode 100644 hdxrate/expfact/__init__.py delete mode 100644 hdxrate/expfact/api.py delete mode 100644 hdxrate/expfact/constants.py delete mode 100644 hdxrate/expfact/kint.py diff --git a/AUTHORS.rst b/AUTHORS.rst index ef236b7..36e749f 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -2,14 +2,7 @@ Credits ======= -This package is a collection of two implemenations of calculating intrinsic deuterium exchange rates of amide hydrogens based on a protein's primary sequence and the temperature and pH of the experiment. - - -ExPfact -------- -https://github.com/skinnersp/exPfact - - Skinner, S. P., Radou, G., Tuma, R., Houwing-Duistermaat, J. J. & Paci, E. Estimating Constraints for Protection Factors from HDX-MS Data. `Biophysical Journal `_ 116, 1194–1203 (2019). +This package is a collection of one implemenation of calculating intrinsic deuterium exchange rates of amide hydrogens based on a protein's primary sequence and the temperature and pH of the experiment. PSX diff --git a/README.rst b/README.rst index bce0c46..0f5c685 100644 --- a/README.rst +++ b/README.rst @@ -16,7 +16,7 @@ HDXrate -Python package collection for HDX intrinsic exchange rate calculation. This package bundles two existing implementations of this calculation, exPfact and PSX. +Python package collection for HDX intrinsic exchange rate calculation. This package bundles existing implementations of this calculation. The calculations are based on the following papers: @@ -49,13 +49,6 @@ Usage Credits ------- -ExPfact -------- -https://github.com/skinnersp/exPfact - - Skinner, S. P., Radou, G., Tuma, R., Houwing-Duistermaat, J. J. & Paci, E. Estimating Constraints for Protection Factors from HDX-MS Data. `Biophysical Journal `__ 116, 1194–1203 (2019). - - PSX ``` https://github.com/Niels-Bohr-Institute-XNS-StructBiophys/PSX diff --git a/comparisons/Rate differences histograms.png b/comparisons/Rate differences histograms.png deleted file mode 100644 index 90481163388fb3ceeab0207d465b2cef11a997ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17503 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 ABme*a diff --git a/comparisons/Rate differences.png b/comparisons/Rate differences.png deleted file mode 100644 index d2bc76f2cc8c983537faf06046dde8289ba09b7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54840 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 QATDcaJlp8}w8dNh2jmz(*Z=?k diff --git a/comparisons/comparison.py b/comparisons/comparison.py deleted file mode 100644 index 0ca9797..0000000 --- a/comparisons/comparison.py +++ /dev/null @@ -1,37 +0,0 @@ -""" -This files calculates and plots intrinsic rates of a sample protein (ecSecB) and looks at differences between -methods. -""" - -from hdxrate.expfact.api import calc_k_int as expfact_k_int -from hdxrate.psx.api import calc_k_int as psx_k_int -import numpy as np -import matplotlib.pyplot as plt - - -sequence = list('MSEQNNTEMTFQIQRIYTKDISFEAPNAPHVFQKDWQPEVKLDLDTASSQLADDVYEVVLRVTVTASLG') -r_number = np.arange(len(sequence)) + 1 - -temperature = 300 -pH = 8. - -psx_poly = psx_k_int(sequence, temperature, pH, 'poly') -psx_oligo = psx_k_int(sequence, temperature, pH, 'oligo') -expfact = expfact_k_int(sequence, temperature, pH) - -fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(15, 5), sharex=True) -ax1.set_yscale('log') -ax1.plot(r_number, psx_poly, label='psx_poly', marker='o', linestyle='None') -ax1.plot(r_number, psx_oligo, label='psx_oligo', marker='o', linestyle='None') -ax1.plot(r_number, expfact, label='expfact', marker='o', linestyle='None') -#ax1.set_ylim(0.1, 1e5) -ax1.set_xlim(0, 80) -ax1.set_ylabel('Intrinsic Exchange \n rate (1/s)') -ax1.legend() - -ax2.plot(r_number, psx_poly / expfact, color='k', label='psx_poly / expfact') -ax2.plot(r_number, psx_oligo / expfact, color='k', linestyle='--', label='psx_oligo / expfact') -ax2.set_ylabel('Fold difference') -ax2.set_xlabel('Residue number') -ax2.legend() -plt.savefig('Rate differences.png') \ No newline at end of file diff --git a/comparisons/random_sequences.py b/comparisons/random_sequences.py deleted file mode 100644 index 22821c4..0000000 --- a/comparisons/random_sequences.py +++ /dev/null @@ -1,48 +0,0 @@ -""" -This files calculates and plots intrinsic rates of randomly generated protein sequences and looks at differences between -methods. - -""" - -from hdxrate.expfact.api import calc_k_int as expfact_k_int -from hdxrate.psx.api import calc_k_int as psx_k_int -import numpy as np -import matplotlib.pyplot as plt - -np.random.seed(43) -amino_acids = list('GALMFWKQESPVICYHRNDT') -repeats = 100 -temperature = 300 -pHs = [6, 7, 8, 9] -fig, axes = plt.subplots(2, 2) - -for ax, pH in zip(axes.flatten(), pHs): - diffs = [] - for i in range(repeats): - sequence = list(np.random.choice(np.array(amino_acids), 800)) - r_number = np.arange(len(sequence)) + 1 - - psx_poly = psx_k_int(sequence, temperature, pH, 'poly') - expfact = expfact_k_int(sequence, temperature, pH) - - d = psx_poly / expfact - diffs += list(psx_poly / expfact) - - diffs = np.array(diffs) - diffs = diffs[~np.isnan(diffs)] # remove NaN - - ax.set_yscale('log') - ax.hist(diffs, bins=75) - ax.set_title(f'pH {pH}') - ax.set_ylabel('Count') - ax.set_xlabel('Fold difference') - ax.set_xlim(0, None) - #print(pH, np.min(diffs), np.max(diffs)) : - # 6 1.586076428945057 4.323111639721702 - # 7 1.6062294252044966 6.2163497448764105 - # 8 1.606402448281534 31.978492966181015 - # 9 1.6064194484834653 45.168683743072926 - -plt.tight_layout() -#plt.show() -plt.savefig('Rate differences histograms.png') diff --git a/examples.rst b/examples.rst deleted file mode 100644 index cd92fd8..0000000 --- a/examples.rst +++ /dev/null @@ -1,20 +0,0 @@ -Examples --------- - -See `/comparisons` for the code to generate the graphs below. - -The graph below shows intrinsic rates of H/D exchange calculated with exPfact / PSX (PSX: 'poly' and 'oligo'). -The overall trend in exchange rates is similar but there is an constant 1.8-2.5 fold difference between different methods, -with outliers up to ~10-fold. - -.. raw:: html - - - -The histograms show fold-difference between exPfact and PSX (poly) for different pH values (T=300K). Differences range -from 1.6-fold to 40-fold. - - -.. raw:: html - - \ No newline at end of file diff --git a/hdxrate/expfact/__init__.py b/hdxrate/expfact/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/hdxrate/expfact/api.py b/hdxrate/expfact/api.py deleted file mode 100644 index 8a8902c..0000000 --- a/hdxrate/expfact/api.py +++ /dev/null @@ -1,64 +0,0 @@ -""" -This script provides and API to expfact intrinsic exchange rate calculation -Copyright (C) 2020 Jochem Smit - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -""" - - -from hdxrate.expfact.kint import calculate_kint_per_residue -import numpy as np - - -def calc_k_int(sequence, temperature, pH): - """ - - Parameters - ---------- - sequence: iterable of strings - Iterable of one-letter code amino acids. Unknown amino acids can be specified with 'X' - temperature: :obj:`float` - Temperature of the labelling buffer in Kelvin - pH: :obj:`float` - pH of labelling buffer. (pH read? pH corrected? pD?) - - Returns - ------- - - k_int: ndarray, float - Numpy array of intrinsic exchange rates (in units of per second) - - """ - - list(sequence).copy() - - k_int_list = [0.] # first residue - for i, (previous, current) in enumerate(zip(sequence[:-1], sequence[1:])): - if previous == 'X' or current == 'X': - k_int_list.append(0.) - elif current == 'P': - k_int_list.append(0.) - else: - k_int = calculate_kint_per_residue(previous, current, i + 2, len(sequence), temperature, pH) - k_int_list.append(k_int) - - return np.array(k_int_list) / 60 - - -if __name__ == '__main__': - chain = list('MSEQNNTEMTFQIQRIYTK') - k_int = calc_k_int(chain, 300, 8.) - - print(k_int) diff --git a/hdxrate/expfact/constants.py b/hdxrate/expfact/constants.py deleted file mode 100644 index 7db5712..0000000 --- a/hdxrate/expfact/constants.py +++ /dev/null @@ -1,103 +0,0 @@ -""" -This script calculates the intrinsic deuteration rates of each residue of a protein into D2O -Copyright (C) 2019 Simon Skinner - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -""" - -from math import exp, log10 - -# Here are the parameters measured in Bai et al. (1993) -# The parameters for D and E are based on the work of Mori and al. (1997) -# and measured by and calculated in the functions acid and base -para = { - "A": [0.00, 0.00, 0.00, 0.00], - "C": [-0.54, -0.46, 0.62, 0.55], - "F": [-0.52, -0.43, -0.235859464059171, 0.0631315866300978], - "G": [-0.22, 0.218176047120386, -0.03, 0.17], - "I": [-0.91, -0.59, -0.73, -0.23], - "K": [-0.56, -0.29, -0.04, 0.12], - "L": [-0.57, -0.13, -0.576252727721677, -0.21], - "M": [-0.64, -0.28, -0.00895484265292644, 0.11], - "N": [-0.58, -0.13, 0.49, 0.38], - "P": [9999, -0.194773472023435, 9999, -0.24], - "Q": [-0.47, -0.27, 0.06, 0.20], - "R": [-0.59, -0.32, 0.0767122542818456, 0.22], - "S": [-0.437992277698594, -0.388518934646472, 0.37, 0.299550285605933], - "T": [-0.79, -0.448073125742265, -0.0662579798400606, 0.20], - "V": [-0.739022273362575, -0.30, -0.701934483299758, -0.14], - "W": [-0.40, -0.44, -0.41, -0.11], - "Y": [-0.41, -0.37, -0.27, 0.05], -} - -rho_Nterm_acid = -1.32 -rho_Nterm_base = 1.62 - -lamb_Cterm_acid = 0.96 -lamb_Cterm_base = -1.80 - -pKD = 15.05 -R = 1.987 - -ka = 10 ** (1.62) / 60 -kb = 10 ** (10.18) / 60 -kw = 10 ** (-1.5) / 60 - -Ea = 14000 -Eb = 17000 -Ew = 19000 - -lamb_cterm_acid = 0.96 - -lamb_cterm_base = -1.80 - - -def get_D(pH): - return 10 ** (-pH) - - -def get_OD(pH): - return 10 ** (pH - pKD) - - -def get_l_DTR(temperature): - return (1. / temperature - 1 / 293.) / R - - -def get_pK_his(temperature): - Ea_his = 7500 - return -log10(10 ** (-7.42) * exp(-Ea_his * (1 / (R * temperature) - 1 / (278 * R)))) - - -def get_pK_asp(temperature): - Ea_asp = 1000 - return -log10(10 ** (-4.48) * exp(-Ea_asp * (1 / (R * temperature) - 1 / (278 * R)))) - - -def get_pK_glu(temperature): - Ea_glu = 1083 - return -log10(10 ** (-4.93) * exp(-Ea_glu * (1 / (R * temperature) - 1 / (278 * R)))) - - -def get_Fta(temperature): - return exp(-Ea * get_l_DTR(temperature)) - - -def get_Ftb(temperature): - return exp(-Eb * get_l_DTR(temperature)) - - -def get_Ftw(temperature): - return exp(-Ew * get_l_DTR(temperature)) diff --git a/hdxrate/expfact/kint.py b/hdxrate/expfact/kint.py deleted file mode 100644 index 624a2f6..0000000 --- a/hdxrate/expfact/kint.py +++ /dev/null @@ -1,140 +0,0 @@ -""" -This script calculates the intrinsic deuteration rates of each residue of a protein into D2O -Copyright (C) 2019 Simon Skinner - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -""" - -#!/usr/bin/python - -# This script calculates the intrinsic deuteration rates of each residue -# of a protein into D2O -# The argument has to be the sequence of the protein in one letter code -# The temperature (in Kelvin) and the pH can be changed -# This script is based on the work of Bai and al. (1993) and the excel table proposed on the Englander group website. Notice that the parameters for E and D has been updated to take into account the work of Mori and al. (1997) -# kint is in min-1 - - -import numpy as np -from hdxrate.expfact.constants import * - - -def calculate_kint_for_sequence(first_residue, last_residue, seq, temperature, pH): - prolines = [] - kint = np.zeros((last_residue)) - kint.fill(-1) - res1 = "" - jj = 0 - for assignment in range(1, len(seq) + 1): - res = seq[jj] - if not res1 == "": - if assignment - first_residue == 0: - kint[assignment - 1] = -1 - elif seq[jj] == "P": - kint[assignment - 1] = -1 - prolines.append(first_residue + jj) - else: - kint[assignment - 1] = calculate_kint_per_residue(res1, res, assignment, len(seq), temperature, pH) - print("**", assignment, len(seq)) - print("***", kint[assignment - 1]) - jj += 1 - res1 = res - print("Residue\tkint") - for residue, value in zip([x for x in range(1, last_residue + 1)], kint): - print("{}\t{}".format(residue, value)) - - return kint, prolines - - -# This function calculate the kint of a residue -# The first argument is the residue i and the second the residue i-1 - -def calculate_kint_per_residue(residue1, residue2, num, length, temperature, pH): - lamb1 = acid(residue2, temperature, pH, "lamb") - rho1 = acid(residue1, temperature, pH, "rho") - - if num == 2: - rho1 += rho_Nterm_acid - elif (num == length): - lamb1 = lamb1 + lamb_Cterm_acid - - Fa = 10 ** (lamb1 + rho1) - lamb2 = base(residue2, temperature, pH, "lamb") - rho2 = base(residue1, temperature, pH, "rho") - - if num == 2: - rho2 += +rho_Nterm_base - elif (num == length): - lamb2 = lamb2 + lamb_Cterm_base - - Fb = 10 ** (lamb2 + rho2) - - kint = Fa * ka * get_D(pH) * get_Fta(temperature) * 60 + Fb * kb * get_OD(pH) * get_Ftb(temperature) * 60 + Fb * \ - kw * get_Ftw(temperature) * 60 - - return kint - - -def acid(residue, temperature, pH, value): - if residue == "H": - lamb = log10( - 10 ** (-0.8 - pH) / (10 ** (-get_pK_his(temperature)) + 10 ** (-pH)) + 10 ** (-get_pK_his(temperature)) / ( - 10 ** (-get_pK_his(temperature)) + 10 ** (-pH))) - rho = log10( - 10 ** (-0.51 - pH) / (10 ** (-get_pK_his(temperature)) + 10 ** (-pH)) + 10 ** (-get_pK_his(temperature)) / ( - 10 ** (-get_pK_his(temperature)) + 10 ** (-pH))) - elif residue == "D": - lamb = log10(10 ** (-0.9 - pH) / (10 ** (-get_pK_asp(temperature)) + 10 ** (-pH)) + 10 ** ( - 0.9 - get_pK_asp(temperature)) / (10 ** (-get_pK_asp(temperature)) + 10 ** (-pH))) - rho = log10(10 ** (-0.12 - pH) / (10 ** (-get_pK_asp(temperature)) + 10 ** (-pH)) + 10 ** ( - 0.58 - get_pK_asp(temperature)) / (10 ** (-get_pK_asp(temperature)) + 10 ** (-pH))) - elif residue == "E": - lamb = log10(10 ** (-0.6 - pH) / (10 ** (-get_pK_glu(temperature)) + 10 ** (-pH)) + 10 ** ( - -0.9 - get_pK_glu(temperature)) / (10 ** (-get_pK_glu(temperature)) + 10 ** (-pH))) - rho = log10(10 ** (-0.27 - pH) / (10 ** (-get_pK_glu(temperature)) + 10 ** (-pH)) + 10 ** ( - 0.31 - get_pK_glu(temperature)) / (10 ** (-get_pK_glu(temperature)) + 10 ** (-pH))) - else: - lamb = para[residue][0] - rho = para[residue][1] - if value == "lamb": - return lamb - elif value == "rho": - return rho - - -def base(residue, temperature, pH, value): - if residue == "H": - lamb = log10(10 ** (0.8 - pH) / (10 ** (-get_pK_his(temperature)) + 10 ** (-pH)) + 10 ** ( - -0.1 - get_pK_his(temperature)) / (10 ** (-get_pK_his(temperature)) + 10 ** (-pH))) - rho = log10(10 ** (0.83 - pH) / (10 ** (-get_pK_his(temperature)) + 10 ** (-pH)) + 10 ** ( - 0.14 - get_pK_his(temperature)) / (10 ** (-get_pK_his(temperature)) + 10 ** (-pH))) - elif residue == "D": - lamb = log10(10 ** (0.69 - pH) / (10 ** (-get_pK_asp(temperature)) + 10 ** (-pH)) + 10 ** ( - 0.1 - get_pK_asp(temperature)) / (10 ** (-get_pK_asp(temperature)) + 10 ** (-pH))) - rho = log10(10 ** (0.6 - pH) / (10 ** (-get_pK_asp(temperature)) + 10 ** (-pH)) + 10 ** ( - -0.18 - get_pK_asp(temperature)) / (10 ** (-get_pK_asp(temperature)) + 10 ** (-pH))) - elif residue == "E": - lamb = log10(10 ** (0.24 - pH) / (10 ** (-get_pK_glu(temperature)) + 10 ** (-pH)) + 10 ** ( - -0.11 - get_pK_glu(temperature)) / (10 ** (-get_pK_glu(temperature)) + 10 ** (-pH))) - rho = log10(10 ** (-0.39 - pH) / (10 ** (-get_pK_glu(temperature)) + 10 ** (-pH)) + 10 ** ( - -0.15 - get_pK_glu(temperature)) / (10 ** (-get_pK_glu(temperature)) + 10 ** (-pH))) - else: - lamb = para[residue][2] - rho = para[residue][3] - - if value == "lamb": - return lamb - elif value == "rho": - return rho diff --git a/hdxrate/hdxrate.py b/hdxrate/hdxrate.py index 12c22ea..8840a2b 100644 --- a/hdxrate/hdxrate.py +++ b/hdxrate/hdxrate.py @@ -1,5 +1,5 @@ """ -This script provides and API to expfact and psx intrinsic exchange rate calculation +This script provides and API to psx intrinsic exchange rate calculation Copyright (C) 2020 Jochem Smit This program is free software: you can redistribute it and/or modify @@ -18,12 +18,10 @@ """ - -from hdxrate.expfact.api import calc_k_int as expfact_k_int from hdxrate.psx.api import calc_k_int as psx_k_int -def k_int_from_sequence(sequence, temperature, pH, module='expfact', **kwargs): +def k_int_from_sequence(sequence, temperature, pH, module='psx', **kwargs): """ Calculate intrinsic rate of amide hydrogen exchange. @@ -40,7 +38,7 @@ def k_int_from_sequence(sequence, temperature, pH, module='expfact', **kwargs): pH: :obj:`float` pH of labelling buffer. (pH read? pH corrected? pD?) module: :obj:`str` - Which module to use for calculating intrinsic rates. Default is 'expfact', options are 'expfact', 'psx' + Which module to use for calculating intrinsic rates. Default is 'psx'. **kwargs: Additional module-specific kwargs to pass on intrinsic rate calculation. See module .api for details. @@ -53,12 +51,10 @@ def k_int_from_sequence(sequence, temperature, pH, module='expfact', **kwargs): """ sequence = list(sequence) - if module == 'expfact': - func = expfact_k_int - elif module == 'psx': + if module == 'psx': func = psx_k_int else: - raise ValueError(f"Invalid value '{module}' specified for module. Options are 'expfact' or 'psx')") + raise ValueError(f"Invalid value '{module}' specified for module. Options are 'psx'") k_int = func(sequence, temperature, pH, **kwargs) diff --git a/hdxrate/psx/IntrinsicExchange.py b/hdxrate/psx/IntrinsicExchange.py index 19aba95..55a4b27 100644 --- a/hdxrate/psx/IntrinsicExchange.py +++ b/hdxrate/psx/IntrinsicExchange.py @@ -3,7 +3,6 @@ ########### import sys import math -import numpy as np ################################################################ @@ -224,16 +223,3 @@ def CalculateExchangeRatesForASingleChain(Chain, Temperature, pH, ReferenceData) return IntrinsicEnchangeRates - -if __name__ == '__main__': - # chain = list( - # 'MSEQNNTEMTFQIQRIYTKDISFEAPNAPHVFQKDWQPEVKLDLDTASSQLADDVYEVVLRVTVTASLGEETAFLCEVQQGGIFSIAGIEGTQMAHCLGAYCPNILFPYARECITSMVSRGTFPQLNLAPVNFDALFMNYLQQQAGEGTEEHQDA') - - chain = list('MSEQNNTEMTFXXXXQIQRIYTK') - - k_int = CalculateExchangeRatesForASingleChain(chain.copy(), 300, 8., 'poly') - np.array(k_int) * 60 - for k, c in zip(k_int, chain): - print(c, k) - -# np.savetxt(r'C:\Users\jhsmi\pp\PyHDX\pyhdx\expfact\k_int_psx_poly.txt', np.array(k_int) * 60) diff --git a/hdxrate/psx/api.py b/hdxrate/psx/api.py index 4137e42..dfd4272 100644 --- a/hdxrate/psx/api.py +++ b/hdxrate/psx/api.py @@ -13,8 +13,6 @@ def calc_k_int(sequence, temperature, pH, reference_data='poly'): Temperature of the labelling buffer in Kelvin pH: :obj:`float` pH of labelling buffer. (pH read? pH corrected? pD?) - module: :obj:`str` - Which module to use for calculating intrinsic rates. Default is 'expfact', options are 'expfact', 'psx' reference_data: :obj:`str` 'poly' or 'oligo' diff --git a/tests/test_hdxrate.py b/tests/test_hdxrate.py index f019ec9..7063fa7 100644 --- a/tests/test_hdxrate.py +++ b/tests/test_hdxrate.py @@ -1,7 +1,6 @@ """Tests for `hdxrate` package.""" import numpy as np -from hdxrate.expfact.api import calc_k_int as expfact_k_int from hdxrate.psx.api import calc_k_int as psx_k_int from hdxrate import k_int_from_sequence @@ -15,9 +14,6 @@ def setup_class(cls): def test_k_int_calculation(self): - expfact = expfact_k_int(self.sequence, 300, 8.) - k_int = k_int_from_sequence(self.sequence, 300, 8., 'expfact') - assert np.allclose(k_int, expfact) psx = psx_k_int(self.sequence, 300, 8., 'poly') k_int = k_int_from_sequence(self.sequence, 300, 8., 'psx')