bindtools 0.2.3__tar.gz → 0.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. {bindtools-0.2.3 → bindtools-0.3.2}/PKG-INFO +57 -4
  2. {bindtools-0.2.3 → bindtools-0.3.2}/README.md +56 -3
  3. bindtools-0.3.2/pyproject.toml +111 -0
  4. bindtools-0.2.3/pyproject.toml → bindtools-0.3.2/pyproject.toml.orig +1 -1
  5. bindtools-0.3.2/src/bindtools/__init__.py +49 -0
  6. bindtools-0.3.2/src/bindtools/binding.py +95 -0
  7. bindtools-0.3.2/src/bindtools/exceptions.py +6 -0
  8. bindtools-0.3.2/src/bindtools/io/__init__.py +4 -0
  9. bindtools-0.3.2/src/bindtools/io/export.py +29 -0
  10. bindtools-0.3.2/src/bindtools/mcmc/__init__.py +19 -0
  11. bindtools-0.3.2/src/bindtools/mcmc/helpers.py +71 -0
  12. bindtools-0.3.2/src/bindtools/mcmc/likelihood.py +49 -0
  13. bindtools-0.3.2/src/bindtools/mcmc/sampler.py +226 -0
  14. bindtools-0.3.2/src/bindtools/models/__init__.py +11 -0
  15. bindtools-0.3.2/src/bindtools/models/binding_model.py +316 -0
  16. bindtools-0.3.2/src/bindtools/models/objective.py +95 -0
  17. bindtools-0.3.2/src/bindtools/models/simulation.py +39 -0
  18. bindtools-0.3.2/src/bindtools/observables/__init__.py +17 -0
  19. bindtools-0.3.2/src/bindtools/observables/transforms.py +91 -0
  20. bindtools-0.3.2/src/bindtools/observables/types.py +80 -0
  21. bindtools-0.3.2/src/bindtools/plotting/__init__.py +8 -0
  22. bindtools-0.3.2/src/bindtools/plotting/fit_plots.py +66 -0
  23. bindtools-0.3.2/src/bindtools/plotting/mcmc_plots.py +38 -0
  24. bindtools-0.3.2/src/bindtools/speciation/__init__.py +34 -0
  25. bindtools-0.3.2/src/bindtools/speciation/analytical.py +250 -0
  26. bindtools-0.3.2/src/bindtools/speciation/numerical.py +139 -0
  27. bindtools-0.3.2/src/bindtools/speciation/scipy_solver.py +45 -0
  28. bindtools-0.2.3/src/bindtools/__init__.py +0 -0
  29. bindtools-0.2.3/src/bindtools/binding.py +0 -1605
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bindtools
3
- Version: 0.2.3
3
+ Version: 0.3.2
4
4
  Keywords: chemistry,analytical chemistry,binding constants,supramolecular
5
5
  Author: Martin Peeks
6
6
  Author-email: Martin Peeks <martinp23@googlemail.com>, m.peeks@unsw.edu.au
@@ -51,11 +51,26 @@ Description-Content-Type: text/markdown
51
51
  - Handles various experimental data including NMR integrations, chemical shifts (NMR `deltaH`/`deltaF`), and linear concentration-weighted observables (UV-vis / fluorescence).
52
52
  - **Bayesian Inference & Uncertainty Quantification**:
53
53
  - Uses `emcee` for Markov Chain Monte Carlo (MCMC) sampling.
54
- - Generates trace/chain convergence plots and corner plots using `corner` and `arviz`.
54
+ - Generates trace/chain convergence plots and corner plots using `corner` and `matplotlib`.
55
55
  - MCMC runs can be serialized and stored as HDF5 files for future analysis.
56
56
 
57
57
  ---
58
58
 
59
+ ## Package Architecture
60
+
61
+ `bindtools` is organized into modular scientific domain subpackages:
62
+
63
+ - **`bindtools.speciation`**: Chemical equilibrium solvers (Numba JIT Newton-Raphson and vectorized cubic analytical solutions for 1:1, 1:2, and 2:1 systems).
64
+ - **`bindtools.observables`**: Physical measurement transforms (`ObsType`, NMR chemical shifts, integrals, and UV-vis / fluorescence linear absorption).
65
+ - **`bindtools.models`**: Model definition (`bindingModel`), simulation helpers, and optimization engine.
66
+ - **`bindtools.mcmc`**: Bayesian parameter estimation (`MCMC`), priors, likelihoods, and HDF5 serialization.
67
+ - **`bindtools.plotting`**: Visualizations for speciation, fit residuals, and MCMC trace/corner diagnostics.
68
+ - **`bindtools.io`**: Data export utilities (`saveFitCSV`).
69
+
70
+ Core symbols can be imported directly from the top level (`import bindtools as bt`), while legacy imports (`from bindtools import binding as bd`) remain fully supported for backwards compatibility.
71
+
72
+ ---
73
+
59
74
  ## Installation
60
75
 
61
76
  `bindtools` is available on PyPI. You can install it directly using `pip`:
@@ -90,7 +105,7 @@ You can compute the equilibrium concentration of free species (components and co
90
105
 
91
106
  ```python
92
107
  import numpy as np
93
- from bindtools import binding as bd
108
+ import bindtools as bt
94
109
 
95
110
  # Define total concentrations: 50 data points of Host (1e-3 M) and Guest (0 to 1e-2 M)
96
111
  component_concs = np.zeros((50, 2))
@@ -113,13 +128,51 @@ logK = np.array([0, 0, 4])
113
128
  # Solve for concentrations at each point
114
129
  results = []
115
130
  for total_concs in component_concs:
116
- spec_concs = bd.getConcs(eq_mat, total_concs, logK)
131
+ spec_concs = bt.getConcs(eq_mat, total_concs, logK)
117
132
  results.append(spec_concs)
118
133
 
119
134
  results = np.array(results)
120
135
  print("First point [H, G, HG]:", results[0])
121
136
  ```
122
137
 
138
+ ### 2. Model Fitting (`bindingModel`)
139
+
140
+ Fit binding models to experimental observables (integrals, chemical shifts, or absorbance):
141
+
142
+ ```python
143
+ import bindtools as bt
144
+
145
+ # Initialize model with stoichiometry, component names, and data
146
+ model = bt.bindingModel(
147
+ eqMat=eq_mat,
148
+ compNames=["H", "G"],
149
+ speciesList=["H", "G", "HG"],
150
+ colToComp=col_to_comp,
151
+ rawData=raw_data,
152
+ )
153
+
154
+ # Prepare parameters and fit
155
+ model.prepModel()
156
+ model.runModel(skip_col=2, method="least_squares")
157
+
158
+ print("Fitted logK:", model.miniResult.params["logHG"].value)
159
+ ```
160
+
161
+ ### 3. Bayesian MCMC & Uncertainty Estimation
162
+
163
+ Quantify parameter uncertainties with MCMC sampling and generate corner plots:
164
+
165
+ ```python
166
+ obs = [bt.ObsType("concMeas")]
167
+ mcmc = bt.MCMC(model, obs, walkers=25, samples=2000)
168
+ sampler, bm = mcmc.run(thin=10)
169
+
170
+ # Diagnostics & plots
171
+ mcmc.plot_chain()
172
+ mcmc.plot_corner()
173
+ mcmc.save("fit_results.hdf")
174
+ ```
175
+
123
176
  ---
124
177
 
125
178
  ## License
@@ -18,11 +18,26 @@
18
18
  - Handles various experimental data including NMR integrations, chemical shifts (NMR `deltaH`/`deltaF`), and linear concentration-weighted observables (UV-vis / fluorescence).
19
19
  - **Bayesian Inference & Uncertainty Quantification**:
20
20
  - Uses `emcee` for Markov Chain Monte Carlo (MCMC) sampling.
21
- - Generates trace/chain convergence plots and corner plots using `corner` and `arviz`.
21
+ - Generates trace/chain convergence plots and corner plots using `corner` and `matplotlib`.
22
22
  - MCMC runs can be serialized and stored as HDF5 files for future analysis.
23
23
 
24
24
  ---
25
25
 
26
+ ## Package Architecture
27
+
28
+ `bindtools` is organized into modular scientific domain subpackages:
29
+
30
+ - **`bindtools.speciation`**: Chemical equilibrium solvers (Numba JIT Newton-Raphson and vectorized cubic analytical solutions for 1:1, 1:2, and 2:1 systems).
31
+ - **`bindtools.observables`**: Physical measurement transforms (`ObsType`, NMR chemical shifts, integrals, and UV-vis / fluorescence linear absorption).
32
+ - **`bindtools.models`**: Model definition (`bindingModel`), simulation helpers, and optimization engine.
33
+ - **`bindtools.mcmc`**: Bayesian parameter estimation (`MCMC`), priors, likelihoods, and HDF5 serialization.
34
+ - **`bindtools.plotting`**: Visualizations for speciation, fit residuals, and MCMC trace/corner diagnostics.
35
+ - **`bindtools.io`**: Data export utilities (`saveFitCSV`).
36
+
37
+ Core symbols can be imported directly from the top level (`import bindtools as bt`), while legacy imports (`from bindtools import binding as bd`) remain fully supported for backwards compatibility.
38
+
39
+ ---
40
+
26
41
  ## Installation
27
42
 
28
43
  `bindtools` is available on PyPI. You can install it directly using `pip`:
@@ -57,7 +72,7 @@ You can compute the equilibrium concentration of free species (components and co
57
72
 
58
73
  ```python
59
74
  import numpy as np
60
- from bindtools import binding as bd
75
+ import bindtools as bt
61
76
 
62
77
  # Define total concentrations: 50 data points of Host (1e-3 M) and Guest (0 to 1e-2 M)
63
78
  component_concs = np.zeros((50, 2))
@@ -80,13 +95,51 @@ logK = np.array([0, 0, 4])
80
95
  # Solve for concentrations at each point
81
96
  results = []
82
97
  for total_concs in component_concs:
83
- spec_concs = bd.getConcs(eq_mat, total_concs, logK)
98
+ spec_concs = bt.getConcs(eq_mat, total_concs, logK)
84
99
  results.append(spec_concs)
85
100
 
86
101
  results = np.array(results)
87
102
  print("First point [H, G, HG]:", results[0])
88
103
  ```
89
104
 
105
+ ### 2. Model Fitting (`bindingModel`)
106
+
107
+ Fit binding models to experimental observables (integrals, chemical shifts, or absorbance):
108
+
109
+ ```python
110
+ import bindtools as bt
111
+
112
+ # Initialize model with stoichiometry, component names, and data
113
+ model = bt.bindingModel(
114
+ eqMat=eq_mat,
115
+ compNames=["H", "G"],
116
+ speciesList=["H", "G", "HG"],
117
+ colToComp=col_to_comp,
118
+ rawData=raw_data,
119
+ )
120
+
121
+ # Prepare parameters and fit
122
+ model.prepModel()
123
+ model.runModel(skip_col=2, method="least_squares")
124
+
125
+ print("Fitted logK:", model.miniResult.params["logHG"].value)
126
+ ```
127
+
128
+ ### 3. Bayesian MCMC & Uncertainty Estimation
129
+
130
+ Quantify parameter uncertainties with MCMC sampling and generate corner plots:
131
+
132
+ ```python
133
+ obs = [bt.ObsType("concMeas")]
134
+ mcmc = bt.MCMC(model, obs, walkers=25, samples=2000)
135
+ sampler, bm = mcmc.run(thin=10)
136
+
137
+ # Diagnostics & plots
138
+ mcmc.plot_chain()
139
+ mcmc.plot_corner()
140
+ mcmc.save("fit_results.hdf")
141
+ ```
142
+
90
143
  ---
91
144
 
92
145
  ## License
@@ -0,0 +1,111 @@
1
+ [build-system]
2
+ requires = ["uv_build"]
3
+ build-backend = "uv_build"
4
+
5
+ [project]
6
+ name = "bindtools"
7
+ version = "0.3.2"
8
+ readme = "README.md"
9
+ classifiers = [
10
+ "Development Status :: 3 - Alpha",
11
+ "Intended Audience :: Science/Research",
12
+ "Programming Language :: Python :: 3.12",
13
+ "Programming Language :: Python :: 3.13",
14
+ "Programming Language :: Python :: 3.14",
15
+ "Topic :: Scientific/Engineering :: Chemistry",
16
+ "Topic :: Scientific/Engineering :: Bio-Informatics",
17
+ ]
18
+ requires-python = ">=3.12"
19
+ keywords = [
20
+ "chemistry",
21
+ "analytical chemistry",
22
+ "binding constants",
23
+ "supramolecular",
24
+ ]
25
+ dependencies = [
26
+ "corner==2.2.3",
27
+ "emcee==3.1.6",
28
+ "h5py>=3.14.0",
29
+ "latex2mathml>=3.81.0",
30
+ "lmfit==1.3.4",
31
+ "matplotlib==3.11.0",
32
+ "numba>=0.66",
33
+ "numpy>=2.3.4",
34
+ "openpyxl>=3.1.5",
35
+ "pandas>=2.3.3",
36
+ "scipy==1.18.0",
37
+ "tqdm==4.68.3",
38
+ "uncertainties==3.2.3",
39
+ ]
40
+
41
+ [[project.authors]]
42
+ name = "Martin Peeks"
43
+ email = "martinp23@googlemail.com"
44
+
45
+ [[project.authors]]
46
+ email = "m.peeks@unsw.edu.au"
47
+
48
+ [project.urls]
49
+ Homepage = "https://github.com/martinp23/bindtools"
50
+ Documentation = "https://readthedocs.org"
51
+ Repository = "https://github.com/martinp23/bindtools.git"
52
+ Issues = "https://github.com/martinp23/bindtools/issues"
53
+
54
+ [tool.ruff]
55
+ exclude = [
56
+ ".bzr",
57
+ ".direnv",
58
+ ".eggs",
59
+ ".git",
60
+ ".git-rewrite",
61
+ ".hg",
62
+ ".ipynb_checkpoints",
63
+ ".mypy_cache",
64
+ ".nox",
65
+ ".pants.d",
66
+ ".pyenv",
67
+ ".pytest_cache",
68
+ ".pytype",
69
+ ".ruff_cache",
70
+ ".svn",
71
+ ".tox",
72
+ ".venv",
73
+ ".vscode",
74
+ "__pypackages__",
75
+ "_build",
76
+ "buck-out",
77
+ "build",
78
+ "dist",
79
+ "node_modules",
80
+ "site-packages",
81
+ "venv",
82
+ ]
83
+ line-length = 120
84
+ indent-width = 4
85
+
86
+ [tool.ruff.lint]
87
+ select = [
88
+ "E4",
89
+ "E7",
90
+ "E9",
91
+ "F",
92
+ ]
93
+ ignore = []
94
+ fixable = ["ALL"]
95
+ unfixable = []
96
+ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
97
+
98
+ [tool.ruff.format]
99
+ quote-style = "double"
100
+ indent-style = "space"
101
+ skip-magic-trailing-comma = false
102
+ line-ending = "auto"
103
+ docstring-code-format = false
104
+ docstring-code-line-length = "dynamic"
105
+
106
+ [dependency-groups]
107
+ dev = [
108
+ "ipykernel>=7.3.0",
109
+ "pytest>=9.1.0",
110
+ "ruff>=0.15.18",
111
+ ]
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "bindtools"
7
- version = "0.2.3"
7
+ version = "0.3.2"
8
8
  readme = "README.md"
9
9
  classifiers = [
10
10
  # How mature is this project? Common values are
@@ -0,0 +1,49 @@
1
+ """bindtools: Python library for supramolecular chemistry modeling, fitting, and speciation.
2
+ """
3
+
4
+ from bindtools.exceptions import EquilibriumError
5
+ from bindtools.speciation import (
6
+ getConcs,
7
+ getConcsScipy,
8
+ calc_analytical_speciation,
9
+ )
10
+ from bindtools.observables import (
11
+ ObsType,
12
+ concToObservable,
13
+ concToDelta,
14
+ concToLinearObs,
15
+ )
16
+ from bindtools.models import (
17
+ bindingModel,
18
+ simulateModel,
19
+ getCalcData,
20
+ )
21
+ from bindtools.mcmc import (
22
+ MCMC,
23
+ )
24
+ from bindtools.plotting import (
25
+ makeFitResidPlot,
26
+ )
27
+ from bindtools.io import (
28
+ saveFitCSV,
29
+ )
30
+ from bindtools import binding
31
+
32
+ __all__ = [
33
+ "binding",
34
+ "EquilibriumError",
35
+ "getConcs",
36
+ "getConcsScipy",
37
+ "calc_analytical_speciation",
38
+ "ObsType",
39
+ "concToObservable",
40
+ "concToDelta",
41
+ "concToLinearObs",
42
+ "bindingModel",
43
+ "simulateModel",
44
+ "getCalcData",
45
+ "MCMC",
46
+ "makeFitResidPlot",
47
+ "saveFitCSV",
48
+ ]
49
+
@@ -0,0 +1,95 @@
1
+ """Compatibility façade re-exporting all public and internal symbols from modular subpackages.
2
+
3
+ This module preserves 100% backwards compatibility with historical code and downstream packages
4
+ (e.g., `import bindtools.binding as bd` or `from bindtools.binding import bindingModel, getConcs`).
5
+ """
6
+
7
+ from bindtools.exceptions import EquilibriumError
8
+ from bindtools.speciation import (
9
+ apply_along_axis_0,
10
+ _apply_along_axis_0,
11
+ specCalc,
12
+ _specJac,
13
+ specJac,
14
+ specObj,
15
+ DoNR,
16
+ getConcs,
17
+ getConcsScipy,
18
+ _solve_cubic_vectorized,
19
+ calc_analytical_speciation,
20
+ _infer_simple_fast_exchange_topology,
21
+ )
22
+ from bindtools.observables import (
23
+ ObsType,
24
+ sigmaMapping,
25
+ deltaToConc,
26
+ concToDelta,
27
+ concToLinearObs,
28
+ concToObservable,
29
+ )
30
+ from bindtools.models import (
31
+ fitfun,
32
+ bindingModel,
33
+ simulateModel,
34
+ getCalcData,
35
+ )
36
+ from bindtools.mcmc import (
37
+ calclnprob,
38
+ log_prob,
39
+ log_prior,
40
+ MCMC,
41
+ doMCMC,
42
+ getTau,
43
+ makeMCMCLabels,
44
+ mcmchelper,
45
+ )
46
+ from bindtools.plotting import (
47
+ makeFitResidPlot,
48
+ plotMCMC,
49
+ plotCorner,
50
+ )
51
+ from bindtools.io import saveFitCSV
52
+
53
+ __all__ = [
54
+ # Exceptions
55
+ "EquilibriumError",
56
+ # Speciation
57
+ "apply_along_axis_0",
58
+ "_apply_along_axis_0",
59
+ "specCalc",
60
+ "_specJac",
61
+ "specJac",
62
+ "specObj",
63
+ "DoNR",
64
+ "getConcs",
65
+ "getConcsScipy",
66
+ "_solve_cubic_vectorized",
67
+ "calc_analytical_speciation",
68
+ "_infer_simple_fast_exchange_topology",
69
+ # Observables
70
+ "ObsType",
71
+ "sigmaMapping",
72
+ "deltaToConc",
73
+ "concToDelta",
74
+ "concToLinearObs",
75
+ "concToObservable",
76
+ # Models & Simulation
77
+ "fitfun",
78
+ "bindingModel",
79
+ "simulateModel",
80
+ "getCalcData",
81
+ # Visualization & IO
82
+ "makeFitResidPlot",
83
+ "plotMCMC",
84
+ "plotCorner",
85
+ "saveFitCSV",
86
+ # MCMC
87
+ "calclnprob",
88
+ "log_prob",
89
+ "log_prior",
90
+ "MCMC",
91
+ "doMCMC",
92
+ "getTau",
93
+ "makeMCMCLabels",
94
+ "mcmchelper",
95
+ ]
@@ -0,0 +1,6 @@
1
+ class EquilibriumError(Exception):
2
+ def __init__(self, message, val, params):
3
+ super().__init__(message)
4
+ self.val = val
5
+ self.params = params
6
+
@@ -0,0 +1,4 @@
1
+ from bindtools.io.export import saveFitCSV
2
+
3
+ __all__ = ["saveFitCSV"]
4
+
@@ -0,0 +1,29 @@
1
+ import numpy as np
2
+ import pandas as pd
3
+ from bindtools.models.simulation import getCalcData
4
+
5
+
6
+ def saveFitCSV(m, mask, filename, xindex=1, xvals=None, xlabel="[G]_tot (M)", labels=None):
7
+ calcData = getCalcData(m)
8
+ compConcs = m.compConcs.copy()
9
+ exptData = m.fcn_opts["exptData"].copy()
10
+
11
+ if labels is None:
12
+ labels = [m.obsList[ii] for ii in mask]
13
+
14
+ if mask is not None:
15
+ calcData = calcData[:, mask]
16
+ exptData = exptData[:, mask]
17
+
18
+ if xvals is None:
19
+ xvals = compConcs[:, xindex]
20
+
21
+ ydata = np.concatenate((exptData, calcData), axis=1)
22
+ data = np.concatenate((xvals[:, np.newaxis], ydata), axis=1)
23
+
24
+ cols = [xlabel, *["expt " + x for x in labels], *["calc " + x for x in labels]]
25
+ print(cols)
26
+ dataExport = pd.DataFrame(data, columns=cols)
27
+
28
+ dataExport.to_csv(filename, index=False)
29
+
@@ -0,0 +1,19 @@
1
+ from bindtools.mcmc.likelihood import calclnprob, log_prob, log_prior
2
+ from bindtools.mcmc.sampler import MCMC
3
+ from bindtools.mcmc.helpers import (
4
+ doMCMC,
5
+ getTau,
6
+ makeMCMCLabels,
7
+ mcmchelper,
8
+ )
9
+
10
+ __all__ = [
11
+ "calclnprob",
12
+ "log_prob",
13
+ "log_prior",
14
+ "MCMC",
15
+ "doMCMC",
16
+ "getTau",
17
+ "makeMCMCLabels",
18
+ "mcmchelper",
19
+ ]
@@ -0,0 +1,71 @@
1
+ from bindtools.mcmc.sampler import MCMC
2
+ from bindtools.observables.types import ObsType
3
+ import emcee
4
+
5
+
6
+ def doMCMC(model, obs, samples=1000, variance=0.1, walkers=10):
7
+ print("Warning: doMCMC() is deprecated. Use the MCMC class and MCMC.run() in future.")
8
+ mcmcModel = MCMC(model, obs, walkers=walkers, samples=samples, variance=variance)
9
+ sampler, bm = mcmcModel.run(ret=True)
10
+ return sampler, bm
11
+
12
+
13
+ def getTau(sampler):
14
+ print("Warning: getTau is deprecated. Use the MCMC class and MCMC.get_tau() in future.")
15
+
16
+ try:
17
+ tau = sampler.get_autocorr_time()
18
+ print(tau)
19
+ except emcee.autocorr.AutocorrError as e:
20
+ print("Warning: Autocorrelation time is likely too short. Check the chain.")
21
+ print(e.tau)
22
+
23
+
24
+ def makeMCMCLabels(model, obs):
25
+ print("Warning: makeMCMCLabels is deprecated. Use the MCMC class and MCMC.labels in future.")
26
+
27
+ params = []
28
+ for pp in model.params:
29
+ if model.params[pp].vary:
30
+ params.append(model.params[pp].name)
31
+
32
+ ss = []
33
+ for pp in obs:
34
+ ss.append(pp.name)
35
+
36
+ ss = list(set(ss))
37
+ ss = ["lnsigma" + x for x in ss]
38
+ params += ss
39
+
40
+ return params
41
+
42
+
43
+ def mcmchelper(
44
+ model, obsList=None, obs_types=None, walkers=25, samples=10000, variance=0.1, thin=500, figName="out.jpg"
45
+ ):
46
+ """
47
+ Helper function to run MCMC on a binding model and plot results.
48
+
49
+ Parameters:
50
+ - model: The binding model to run MCMC on.
51
+ - obsList: List of observable types.
52
+ - obs_types: Optional list of ObsType instances.
53
+ - walkers: Number of walkers for MCMC.
54
+ - samples: Number of samples to draw.
55
+ - variance: Variance for the MCMC sampling.
56
+ - thin: Thinning factor for the samples.
57
+ - figName: Name of the output figure file.
58
+ """
59
+ if obs_types is None:
60
+ if obsList is None:
61
+ raise ValueError("Either obsList or obs_types must be provided.")
62
+ obs_types = [ObsType("deltaH")] * len(obsList)
63
+
64
+ mcmc = MCMC(model, obs_types, walkers=walkers, samples=samples, variance=variance)
65
+ mcmc.run(thin=thin)
66
+
67
+ mcmc.plot_chain()
68
+ mcmc.get_tau()
69
+ ff = mcmc.plot_corner()
70
+ ff.savefig(figName, dpi=150)
71
+ return mcmc
@@ -0,0 +1,49 @@
1
+ import math
2
+ import numpy as np
3
+ from numba import jit
4
+
5
+ from bindtools.models.objective import fitfun
6
+
7
+
8
+ @jit(nopython=True, nogil=True, cache=True)
9
+ def calclnprob(r, lnsigma):
10
+ r = -0.5 * np.sum(np.divide(r, np.exp(lnsigma)) ** 2 + np.log(2 * np.pi) + 2 * lnsigma)
11
+
12
+ if math.isnan(r):
13
+ print("Probability function returned NaN, fudging to -inf.")
14
+ return -np.inf
15
+ return r
16
+
17
+
18
+ @jit(nopython=True, nogil=True, cache=True)
19
+ def log_prior(val, bounds):
20
+ for ii in range(len(val)):
21
+ if not (bounds[ii][0] < val[ii] < bounds[ii][1]):
22
+ return -np.inf
23
+ return 0.0
24
+
25
+
26
+ def log_prob(params, fcn_opts, bounds):
27
+ lp = log_prior(params, bounds)
28
+
29
+ if not np.isfinite(lp):
30
+ return -np.inf
31
+
32
+ mapping = fcn_opts["sigmaMapping"]
33
+ lnsigmaVals = params[-(max(mapping) + 1) :]
34
+ lnsigma = np.array([lnsigmaVals[ii] for ii in mapping])
35
+
36
+ pp = np.zeros(
37
+ len(params) + np.shape(fcn_opts["compConcs"])[1]
38
+ ) # need extra parameters - for logK=0 - for each component in the eqMat
39
+
40
+ pp[-len(params) :] = params
41
+
42
+ fcn_opts["ret"] = "residual"
43
+ r = np.array(fitfun(pp, fcn_opts))
44
+ if np.isnan(r).any():
45
+ return -np.inf
46
+
47
+ rout = calclnprob(r, lnsigma)
48
+ return rout
49
+