From 6207f195d6fc52ac3bde525eda23a77528c16752 Mon Sep 17 00:00:00 2001 From: Michael Harms Date: Tue, 23 Jul 2024 15:38:37 -0700 Subject: [PATCH 01/17] building main api, intermediate commit --- docs/badges/coverage-badge.svg | 1 + docs/badges/ghwf.svg | 35 ++ docs/badges/rtd.svg | 1 + docs/badges/tests-badge.svg | 1 + reports/flake.txt | 542 +++++++++++++++++++ reports/junit/junit.xml | 1 + run_all_tests.sh | 2 + src/linkage/__init__.py | 14 +- src/linkage/experiment/__init__.py | 2 +- src/linkage/experiment/experiment.py | 87 ++- src/linkage/experiment/experimental_point.py | 164 ++++++ src/linkage/models/base.py | 6 +- src/linkage/models/six_state_edta.py | 18 +- src/linkage/organizer/__init__.py | 1 + src/linkage/organizer/global_fit.py | 267 +++++++++ tests/linkage/experiment/test_titrator.py | 21 + 16 files changed, 1097 insertions(+), 66 deletions(-) create mode 100644 docs/badges/coverage-badge.svg create mode 100644 docs/badges/ghwf.svg create mode 100644 docs/badges/rtd.svg create mode 100644 docs/badges/tests-badge.svg create mode 100644 reports/flake.txt create mode 100644 reports/junit/junit.xml create mode 100644 src/linkage/experiment/experimental_point.py create mode 100644 src/linkage/organizer/__init__.py create mode 100644 src/linkage/organizer/global_fit.py create mode 100644 tests/linkage/experiment/test_titrator.py diff --git a/docs/badges/coverage-badge.svg b/docs/badges/coverage-badge.svg new file mode 100644 index 0000000..c75c126 --- /dev/null +++ b/docs/badges/coverage-badge.svg @@ -0,0 +1 @@ +coverage: 29.51%coverage29.51% \ No newline at end of file diff --git a/docs/badges/ghwf.svg b/docs/badges/ghwf.svg new file mode 100644 index 0000000..0b6100d --- /dev/null +++ b/docs/badges/ghwf.svg @@ -0,0 +1,35 @@ + + dataprob - failing + + + + + + + + + + + + + + + + + + dataprob + + + + + + + failing + + + + + + diff --git a/docs/badges/rtd.svg b/docs/badges/rtd.svg new file mode 100644 index 0000000..86371bf --- /dev/null +++ b/docs/badges/rtd.svg @@ -0,0 +1 @@ +docsdocsunknownunknown \ No newline at end of file diff --git a/docs/badges/tests-badge.svg b/docs/badges/tests-badge.svg new file mode 100644 index 0000000..a9cdf90 --- /dev/null +++ b/docs/badges/tests-badge.svg @@ -0,0 +1 @@ +tests: 1tests1 \ No newline at end of file diff --git a/reports/flake.txt b/reports/flake.txt new file mode 100644 index 0000000..a27e304 --- /dev/null +++ b/reports/flake.txt @@ -0,0 +1,542 @@ +./build/lib/linkage/__init__.py:2:1: F401 'linkage.experiment.Experiment' imported but unused +./build/lib/linkage/__init__.py:3:1: F401 'linkage.organizer.GlobalFit' imported but unused +./build/lib/linkage/__init__.py:12:52: E231 missing whitespace after ',' +./build/lib/linkage/__init__.py:13:36: W292 no newline at end of file +./build/lib/linkage/cli.py:2:1: F401 'linkage' imported but unused +./build/lib/linkage/cli.py:7:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/cli.py:8:1: W293 blank line contains whitespace +./build/lib/linkage/cli.py:15:1: W293 blank line contains whitespace +./build/lib/linkage/cli.py:16:5: F841 local variable 'args' is assigned to but never used +./build/lib/linkage/cli.py:20:1: W293 blank line contains whitespace +./build/lib/linkage/cli.py:20:5: W292 no newline at end of file +./build/lib/linkage/experiment/__init__.py:2:1: F401 'linkage.experiment.experiment.Experiment' imported but unused +./build/lib/linkage/experiment/baseline_corrector.py:4:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/experiment/baseline_corrector.py:4:25: E231 missing whitespace after ',' +./build/lib/linkage/experiment/baseline_corrector.py:4:27: E231 missing whitespace after ',' +./build/lib/linkage/experiment/baseline_corrector.py:4:42: E231 missing whitespace after ',' +./build/lib/linkage/experiment/baseline_corrector.py:4:55: E231 missing whitespace after ',' +./build/lib/linkage/experiment/baseline_corrector.py:7:68: W291 trailing whitespace +./build/lib/linkage/experiment/baseline_corrector.py:8:70: W291 trailing whitespace +./build/lib/linkage/experiment/baseline_corrector.py:9:46: W291 trailing whitespace +./build/lib/linkage/experiment/baseline_corrector.py:10:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/baseline_corrector.py:26:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/baseline_corrector.py:32:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/baseline_corrector.py:41:21: E231 missing whitespace after ',' +./build/lib/linkage/experiment/baseline_corrector.py:41:23: E231 missing whitespace after ',' +./build/lib/linkage/experiment/baseline_corrector.py:41:28: E231 missing whitespace after ',' +./build/lib/linkage/experiment/baseline_corrector.py:41:45: E231 missing whitespace after ',' +./build/lib/linkage/experiment/baseline_corrector.py:42:18: E231 missing whitespace after ',' +./build/lib/linkage/experiment/baseline_corrector.py:42:47: E231 missing whitespace after ',' +./build/lib/linkage/experiment/baseline_corrector.py:42:51: E231 missing whitespace after ',' +./build/lib/linkage/experiment/baseline_corrector.py:43:18: E231 missing whitespace after ',' +./build/lib/linkage/experiment/baseline_corrector.py:43:45: E231 missing whitespace after ',' +./build/lib/linkage/experiment/baseline_corrector.py:43:49: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:6:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/experiment/experiment.py:16:42: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:25:76: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:27:91: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:29:71: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:29:84: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:30:31: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:34:49: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:34:66: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:35:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:36:46: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:40:49: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:59:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:74:35: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:79:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:84:51: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:87:46: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:90:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:101:53: E231 missing whitespace after ':' +./build/lib/linkage/experiment/experiment.py:102:63: E231 missing whitespace after ':' +./build/lib/linkage/experiment/experiment.py:103:56: E231 missing whitespace after ':' +./build/lib/linkage/experiment/experiment.py:104:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:105:34: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:105:45: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:116:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:3:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/experiment/experimental_point.py:6:13: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:8:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:16:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:34:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:44:1: E303 too many blank lines (3) +./build/lib/linkage/experiment/experimental_point.py:46:66: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:47:67: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:59:47: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:60:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:86:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:89:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:92:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:94:24: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:94:30: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:96:75: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:100:49: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:101:42: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:109:49: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:120:38: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:121:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:142:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:145:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:147:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:149:24: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:149:35: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:149:41: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:153:17: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:162:41: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:162:76: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:163:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:164:35: W292 no newline at end of file +./build/lib/linkage/experiment/titrator.py:6:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/experiment/titrator.py:13:55: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:14:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:21:32: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:26:32: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:31:51: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:33:90: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:34:67: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:35:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:42:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:46:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:51:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:59:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:61:47: E231 missing whitespace after ',' +./build/lib/linkage/experiment/titrator.py:62:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:69:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:93:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:102:1: W293 blank line contains whitespace +./build/lib/linkage/models/__init__.py:2:1: F401 'linkage.models.six_state_edta.SixStateEDTA' imported but unused +./build/lib/linkage/models/base.py:4:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/models/base.py:8:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:9:23: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:9:35: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:10:27: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:14:30: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:14:35: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:14:40: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:14:45: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:14:50: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:18:30: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:18:35: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:19:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:22:80: W292 no newline at end of file +./build/lib/linkage/models/six_state_edta.py:10:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/models/six_state_edta.py:17:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:18:25: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:18:28: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:18:31: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:18:34: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:18:37: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:18:40: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:18:43: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:18:46: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:18:49: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:20:79: W291 trailing whitespace +./build/lib/linkage/models/six_state_edta.py:21:82: W291 trailing whitespace +./build/lib/linkage/models/six_state_edta.py:24:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:30:50: E225 missing whitespace around operator +./build/lib/linkage/models/six_state_edta.py:33:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:35:31: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:35:36: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:35:42: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:35:48: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:35:56: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:35:61: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:38:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:40:47: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:40:53: E225 missing whitespace around operator +./build/lib/linkage/models/six_state_edta.py:40:56: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:40:62: E225 missing whitespace around operator +./build/lib/linkage/models/six_state_edta.py:42:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:45:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:50:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:53:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:54:73: W291 trailing whitespace +./build/lib/linkage/models/six_state_edta.py:56:48: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:60:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:63:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:64:23: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:64:35: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:66:74: W291 trailing whitespace +./build/lib/linkage/models/six_state_edta.py:67:56: W291 trailing whitespace +./build/lib/linkage/models/six_state_edta.py:68:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:75:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:79:79: W291 trailing whitespace +./build/lib/linkage/models/six_state_edta.py:85:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:87:32: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:87:35: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:87:38: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:87:41: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:87:44: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:87:47: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:87:50: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:87:53: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:88:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:94:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:98:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:102:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:105:9: E741 ambiguous variable name 'I' +./build/lib/linkage/models/six_state_edta.py:111:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:113:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:116:30: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:116:35: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:116:40: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:116:45: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:116:50: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:120:30: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:120:35: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:121:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:125:1: W391 blank line at end of file +./build/lib/linkage/organizer/__init__.py:1:1: F401 'linkage.organizer.global_fit.GlobalFit' imported but unused +./build/lib/linkage/organizer/__init__.py:1:51: W292 no newline at end of file +./build/lib/linkage/organizer/global_fit.py:9:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/organizer/global_fit.py:11:22: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:11:32: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:14:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:35:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:44:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:45:5: E303 too many blank lines (2) +./build/lib/linkage/organizer/global_fit.py:47:61: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:49:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:55:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:56:59: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:58:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:59:58: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:66:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:72:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:79:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:83:15: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:85:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:87:53: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:97:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:98:47: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:113:41: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:120:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:123:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:130:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:132:5: E303 too many blank lines (2) +./build/lib/linkage/organizer/global_fit.py:134:69: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:137:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:142:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:145:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:146:61: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:147:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:150:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:160:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:169:57: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:172:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:174:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:176:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:178:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:179:75: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:180:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:183:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:194:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:196:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:203:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:208:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:213:48: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:216:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:217:25: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:218:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:220:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:226:17: F841 local variable 'fudge_species_index' is assigned to but never used +./build/lib/linkage/organizer/global_fit.py:232:78: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:234:59: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:235:34: F821 undefined name 'fudge_index' +./build/lib/linkage/organizer/global_fit.py:241:40: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:247:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:253:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:265:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:266:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:267:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:267:9: W292 no newline at end of file +./src/linkage/__init__.py:2:1: F401 'linkage.experiment.Experiment' imported but unused +./src/linkage/__init__.py:3:1: F401 'linkage.organizer.GlobalFit' imported but unused +./src/linkage/__init__.py:12:52: E231 missing whitespace after ',' +./src/linkage/__init__.py:13:36: W292 no newline at end of file +./src/linkage/experiment/__init__.py:2:1: F401 'linkage.experiment.experiment.Experiment' imported but unused +./src/linkage/experiment/baseline_corrector.py:4:1: E302 expected 2 blank lines, found 1 +./src/linkage/experiment/baseline_corrector.py:4:25: E231 missing whitespace after ',' +./src/linkage/experiment/baseline_corrector.py:4:27: E231 missing whitespace after ',' +./src/linkage/experiment/baseline_corrector.py:4:42: E231 missing whitespace after ',' +./src/linkage/experiment/baseline_corrector.py:4:55: E231 missing whitespace after ',' +./src/linkage/experiment/baseline_corrector.py:7:68: W291 trailing whitespace +./src/linkage/experiment/baseline_corrector.py:8:70: W291 trailing whitespace +./src/linkage/experiment/baseline_corrector.py:9:46: W291 trailing whitespace +./src/linkage/experiment/baseline_corrector.py:10:1: W293 blank line contains whitespace +./src/linkage/experiment/baseline_corrector.py:26:1: W293 blank line contains whitespace +./src/linkage/experiment/baseline_corrector.py:32:1: W293 blank line contains whitespace +./src/linkage/experiment/baseline_corrector.py:41:21: E231 missing whitespace after ',' +./src/linkage/experiment/baseline_corrector.py:41:23: E231 missing whitespace after ',' +./src/linkage/experiment/baseline_corrector.py:41:28: E231 missing whitespace after ',' +./src/linkage/experiment/baseline_corrector.py:41:45: E231 missing whitespace after ',' +./src/linkage/experiment/baseline_corrector.py:42:18: E231 missing whitespace after ',' +./src/linkage/experiment/baseline_corrector.py:42:47: E231 missing whitespace after ',' +./src/linkage/experiment/baseline_corrector.py:42:51: E231 missing whitespace after ',' +./src/linkage/experiment/baseline_corrector.py:43:18: E231 missing whitespace after ',' +./src/linkage/experiment/baseline_corrector.py:43:45: E231 missing whitespace after ',' +./src/linkage/experiment/baseline_corrector.py:43:49: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:6:1: E302 expected 2 blank lines, found 1 +./src/linkage/experiment/experiment.py:16:42: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:25:76: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:27:91: W291 trailing whitespace +./src/linkage/experiment/experiment.py:29:71: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:29:84: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:30:31: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:34:49: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:34:66: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:35:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:36:46: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:40:49: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:59:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:74:35: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:79:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:84:51: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:87:46: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:90:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:101:53: E231 missing whitespace after ':' +./src/linkage/experiment/experiment.py:102:63: E231 missing whitespace after ':' +./src/linkage/experiment/experiment.py:103:56: E231 missing whitespace after ':' +./src/linkage/experiment/experiment.py:104:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:105:34: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:105:45: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:116:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:3:1: E302 expected 2 blank lines, found 1 +./src/linkage/experiment/experimental_point.py:6:13: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:8:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:16:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:34:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:44:1: E303 too many blank lines (3) +./src/linkage/experiment/experimental_point.py:46:66: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:47:67: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:59:47: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:60:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:86:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:89:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:92:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:94:24: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:94:30: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:96:75: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:100:49: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:101:42: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:109:49: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:120:38: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:121:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:142:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:145:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:147:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:149:24: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:149:35: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:149:41: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:153:17: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:162:41: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:162:76: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:163:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:164:35: W292 no newline at end of file +./src/linkage/experiment/titrator.py:6:1: E302 expected 2 blank lines, found 1 +./src/linkage/experiment/titrator.py:13:55: W291 trailing whitespace +./src/linkage/experiment/titrator.py:14:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:21:32: W291 trailing whitespace +./src/linkage/experiment/titrator.py:26:32: W291 trailing whitespace +./src/linkage/experiment/titrator.py:31:51: W291 trailing whitespace +./src/linkage/experiment/titrator.py:33:90: W291 trailing whitespace +./src/linkage/experiment/titrator.py:34:67: W291 trailing whitespace +./src/linkage/experiment/titrator.py:35:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:42:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:46:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:51:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:59:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:61:47: E231 missing whitespace after ',' +./src/linkage/experiment/titrator.py:62:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:69:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:93:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:102:1: W293 blank line contains whitespace +./src/linkage/models/__init__.py:2:1: F401 'linkage.models.six_state_edta.SixStateEDTA' imported but unused +./src/linkage/models/base.py:4:1: E302 expected 2 blank lines, found 1 +./src/linkage/models/base.py:8:1: W293 blank line contains whitespace +./src/linkage/models/base.py:9:23: E231 missing whitespace after ',' +./src/linkage/models/base.py:9:35: E231 missing whitespace after ',' +./src/linkage/models/base.py:10:27: E231 missing whitespace after ',' +./src/linkage/models/base.py:14:30: E231 missing whitespace after ',' +./src/linkage/models/base.py:14:35: E231 missing whitespace after ',' +./src/linkage/models/base.py:14:40: E231 missing whitespace after ',' +./src/linkage/models/base.py:14:45: E231 missing whitespace after ',' +./src/linkage/models/base.py:14:50: E231 missing whitespace after ',' +./src/linkage/models/base.py:18:30: E231 missing whitespace after ',' +./src/linkage/models/base.py:18:35: E231 missing whitespace after ',' +./src/linkage/models/base.py:19:1: W293 blank line contains whitespace +./src/linkage/models/base.py:22:80: W292 no newline at end of file +./src/linkage/models/six_state_edta.py:10:1: E302 expected 2 blank lines, found 1 +./src/linkage/models/six_state_edta.py:17:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:18:25: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:18:28: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:18:31: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:18:34: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:18:37: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:18:40: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:18:43: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:18:46: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:18:49: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:20:79: W291 trailing whitespace +./src/linkage/models/six_state_edta.py:21:82: W291 trailing whitespace +./src/linkage/models/six_state_edta.py:24:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:30:50: E225 missing whitespace around operator +./src/linkage/models/six_state_edta.py:33:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:35:31: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:35:36: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:35:42: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:35:48: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:35:56: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:35:61: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:38:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:40:47: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:40:53: E225 missing whitespace around operator +./src/linkage/models/six_state_edta.py:40:56: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:40:62: E225 missing whitespace around operator +./src/linkage/models/six_state_edta.py:42:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:45:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:50:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:53:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:54:73: W291 trailing whitespace +./src/linkage/models/six_state_edta.py:56:48: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:60:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:63:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:64:23: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:64:35: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:66:74: W291 trailing whitespace +./src/linkage/models/six_state_edta.py:67:56: W291 trailing whitespace +./src/linkage/models/six_state_edta.py:68:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:75:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:79:79: W291 trailing whitespace +./src/linkage/models/six_state_edta.py:85:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:87:32: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:87:35: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:87:38: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:87:41: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:87:44: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:87:47: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:87:50: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:87:53: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:88:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:94:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:98:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:102:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:105:9: E741 ambiguous variable name 'I' +./src/linkage/models/six_state_edta.py:111:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:113:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:116:30: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:116:35: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:116:40: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:116:45: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:116:50: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:120:30: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:120:35: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:121:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:125:1: W391 blank line at end of file +./src/linkage/organizer/__init__.py:1:1: F401 'linkage.organizer.global_fit.GlobalFit' imported but unused +./src/linkage/organizer/__init__.py:1:51: W292 no newline at end of file +./src/linkage/organizer/global_fit.py:9:1: E302 expected 2 blank lines, found 1 +./src/linkage/organizer/global_fit.py:11:22: E231 missing whitespace after ',' +./src/linkage/organizer/global_fit.py:11:32: E231 missing whitespace after ',' +./src/linkage/organizer/global_fit.py:14:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:35:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:44:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:45:5: E303 too many blank lines (2) +./src/linkage/organizer/global_fit.py:47:61: W291 trailing whitespace +./src/linkage/organizer/global_fit.py:49:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:55:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:56:59: E231 missing whitespace after ',' +./src/linkage/organizer/global_fit.py:58:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:59:58: W291 trailing whitespace +./src/linkage/organizer/global_fit.py:66:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:72:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:79:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:83:15: W291 trailing whitespace +./src/linkage/organizer/global_fit.py:85:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:87:53: W291 trailing whitespace +./src/linkage/organizer/global_fit.py:97:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:98:47: W291 trailing whitespace +./src/linkage/organizer/global_fit.py:113:41: W291 trailing whitespace +./src/linkage/organizer/global_fit.py:120:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:123:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:130:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:132:5: E303 too many blank lines (2) +./src/linkage/organizer/global_fit.py:134:69: W291 trailing whitespace +./src/linkage/organizer/global_fit.py:137:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:142:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:145:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:146:61: E231 missing whitespace after ',' +./src/linkage/organizer/global_fit.py:147:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:150:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:160:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:169:57: E231 missing whitespace after ',' +./src/linkage/organizer/global_fit.py:172:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:174:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:176:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:178:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:179:75: E231 missing whitespace after ',' +./src/linkage/organizer/global_fit.py:180:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:183:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:194:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:196:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:203:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:208:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:213:48: E231 missing whitespace after ',' +./src/linkage/organizer/global_fit.py:216:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:217:25: E231 missing whitespace after ',' +./src/linkage/organizer/global_fit.py:218:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:220:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:232:78: W291 trailing whitespace +./src/linkage/organizer/global_fit.py:234:59: E231 missing whitespace after ',' +./src/linkage/organizer/global_fit.py:241:40: E231 missing whitespace after ',' +./src/linkage/organizer/global_fit.py:247:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:253:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:265:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:266:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:267:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:267:9: W292 no newline at end of file +./tests/linkage/conftest.py:5:1: E302 expected 2 blank lines, found 1 +./tests/linkage/conftest.py:36:63: E231 missing whitespace after ',' +./tests/linkage/conftest.py:50:49: E231 missing whitespace after ',' +./tests/linkage/conftest.py:56:9: F841 local variable 'patterns' is assigned to but never used +./tests/linkage/conftest.py:61:68: E231 missing whitespace after ',' +./tests/linkage/conftest.py:66:64: E231 missing whitespace after ',' +./tests/linkage/conftest.py:66:65: F541 f-string is missing placeholders +./tests/linkage/conftest.py:73:58: E231 missing whitespace after ',' +./tests/linkage/conftest.py:77:58: E231 missing whitespace after ',' +./tests/linkage/conftest.py:87:1: E302 expected 2 blank lines, found 1 +./tests/linkage/conftest.py:89:41: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:1:1: F401 'pytest' imported but unused +./tests/linkage/experiment/test_titrator.py:9:1: E302 expected 2 blank lines, found 1 +./tests/linkage/experiment/test_titrator.py:10:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_titrator.py:11:35: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:11:40: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:11:42: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:11:46: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:12:38: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:12:43: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:12:46: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:12:50: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:13:33: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:14:37: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:14:48: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:15:37: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:16:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_titrator.py:19:31: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:21:1: W391 blank line at end of file +6 E225 missing whitespace around operator +214 E231 missing whitespace after ',' +18 E302 expected 2 blank lines, found 1 +6 E303 too many blank lines (3) +2 E741 ambiguous variable name 'I' +12 F401 'linkage.experiment.Experiment' imported but unused +1 F541 f-string is missing placeholders +1 F821 undefined name 'fudge_index' +3 F841 local variable 'args' is assigned to but never used +64 W291 trailing whitespace +11 W292 no newline at end of file +187 W293 blank line contains whitespace +3 W391 blank line at end of file +528 diff --git a/reports/junit/junit.xml b/reports/junit/junit.xml new file mode 100644 index 0000000..1542c1f --- /dev/null +++ b/reports/junit/junit.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/run_all_tests.sh b/run_all_tests.sh index f7231ae..64f19d6 100644 --- a/run_all_tests.sh +++ b/run_all_tests.sh @@ -34,3 +34,5 @@ sleep 1 wget https://github.com/harmslab/linkage/actions/workflows/python-app.yml/badge.svg -O ghwf.svg wget https://readthedocs.org/projects/linkage/badge/?version=latest -O rtd.svg + +mv *.svg docs/badges/ diff --git a/src/linkage/__init__.py b/src/linkage/__init__.py index 4e4e1d6..2ab7b9a 100644 --- a/src/linkage/__init__.py +++ b/src/linkage/__init__.py @@ -1,3 +1,13 @@ +import linkage +from linkage.experiment import Experiment +from linkage.organizer import GlobalFit -from . import models -from . import experiment \ No newline at end of file + +# Make a list of all classes in linkage.models +available_models = [] +for _k in linkage.models.__dict__: + if _k.startswith("_"): + continue + + if issubclass(type(linkage.models.__dict__[_k]),type): + available_models.append(_k) \ No newline at end of file diff --git a/src/linkage/experiment/__init__.py b/src/linkage/experiment/__init__.py index 76b1e98..a625657 100644 --- a/src/linkage/experiment/__init__.py +++ b/src/linkage/experiment/__init__.py @@ -1,2 +1,2 @@ -from .experiment import Experiment \ No newline at end of file +from linkage.experiment.experiment import Experiment diff --git a/src/linkage/experiment/experiment.py b/src/linkage/experiment/experiment.py index 90a8af0..eb68fcc 100644 --- a/src/linkage/experiment/experiment.py +++ b/src/linkage/experiment/experiment.py @@ -21,11 +21,15 @@ def __init__(self, err = "expt_data should be a dataframe or spreadsheet with a 'injection' column\n" raise ValueError(err) + if "ignore_point" not in self._expt_data.columns: + self._expt_data["ignore_point"] = np.zeros(len(self._expt_data),dtype=bool) + # If there is no "0" injections start -- like in ITC, for example -- add this with # np.nan for all non-injection values if not np.isclose(self._expt_data.loc[self._expt_data.index[0],"injection"],0): new_row = dict([(c,[np.nan]) for c in self._expt_data.columns]) new_row["injection"] = [0.0] + new_row["ignore_point"] = [True] new_row = pd.DataFrame(new_row) self._expt_data = pd.concat((new_row,self._expt_data),ignore_index=True) @@ -43,53 +47,16 @@ def __init__(self, cell_volume=cell_volume, injection_array=np.array(self._expt_data["injection"]), constant_volume=constant_volume) - - self._macrospecies = np.array(self._expt_concs.columns[2:]) - self._conc_array = np.array(self._expt_concs.loc[:,self._macrospecies]) + # Make sure conc_to_float is sane if conc_to_float is not None: - self._floating_conc = True - - self._mask = self._macrospecies == conc_to_float - if np.sum(self._mask) != 1: - err = "conc_to_float should be one of the macrospecies in the dataset\n" + if conc_to_float not in self._expt_concs.columns: + err = "conc_to_float is not a macrospecies in the experiment\n" raise ValueError(err) - else: - self._mask = np.ones(len(self._macrospecies),dtype=bool) - self._floating_conc = False - - - self._observable_columns = {} - - @property - def expt_data(self): - return self._expt_data + self._conc_to_float = conc_to_float + self._observables = {} - @property - def expt_concs(self): - return self._expt_concs - - @property - def macrospecies(self): - return self._macrospecies - - @property - def conc_array(self): - - return self._conc_array - - def get_scaled_conc_array(self,conc_float_scalar=1.0): - """ - Get the concentration array with the species indicated in conc_to_float - scaled by conc_float_scalar. - """ - - conc_array = self._conc_array.copy() - conc_array[:,self._mask] = conc_array[:,self._mask]*conc_float_scalar - - return conc_array - def add_observable(self, column_name, obs_type, @@ -125,18 +92,36 @@ def add_observable(self, err = "denominator must be specified for a 'spec' experiment.\n" raise ValueError(err) - if denominator not in self.macrospecies: - err = f"denominator must be one of: {','.join(self.macrospecies)}\n" + macrospecies = self._expt_concs.columns + macrospecies = [m for m in macrospecies if m != "injection"] + if denominator not in macrospecies: + err = f"denominator must be one of: {','.join(macrospecies)}\n" raise ValueError(err) - self._observable_columns[column_name] = {"obs_type":obs_type, - "observable_species":observable_species, - "denominator":denominator} + self._observables[column_name] = {"obs_type":obs_type, + "observable_species":observable_species, + "denominator":denominator} + def add_expt_conc_column(self,new_column,conc_vector=None): + + if conc_vector is None: + conc_vector = np.zeros(len(self._expt_concs)) + + if new_column not in self._expt_concs.columns: + self._expt_concs[new_column] = conc_vector + + @property + def expt_data(self): + return self._expt_data + + @property + def expt_concs(self): + return self._expt_concs + @property - def observable_columns(self): - return self._observable_columns + def observables(self): + return self._observables @property - def floating_conc(self): - return self._floating_conc + def conc_to_float(self): + return self._conc_to_float diff --git a/src/linkage/experiment/experimental_point.py b/src/linkage/experiment/experimental_point.py new file mode 100644 index 0000000..1d36dbf --- /dev/null +++ b/src/linkage/experiment/experimental_point.py @@ -0,0 +1,164 @@ +import numpy as np + +class ExperimentalPoint: + """ + Class for storing an individual experimental data point. Should be sub- + classed. + """ + + def __init__(self, + idx, + expt_idx, + obs_key): + """ + Should be sub-classed. + """ + + self._idx = idx + self._expt_idx = expt_idx + self._obs_key = obs_key + + @property + def idx(self): + """ + Index of point in experimental array. + """ + return self._idx + + @property + def expt_idx(self): + """ + Index of experiment. + """ + return self._expt_idx + + @property + def obs_key(self): + """ + Name of observable. + """ + return self._obs_key + + + +class SpecPoint(ExperimentalPoint): + """ + Class holds experimental data for an individual spectroscopic + experimental data point and how it links to the binding model. + """ + + def __init__(self, + idx, + expt_idx, + obs_key, + obs_mask, + denom, + micro_array, + macro_array): + """ + Initialize a spectroscopic data point. + + Parameters + ---------- + idx : int + index of point in the experimental array + expt_idx : int + index of the experiment itself (allowing multiple experiments) + obs_key : str + key pointing to observable from the experiment + obs_mask : np.ndarray (bool or int) + mask that grabs microscopic species from micro_array that correspond + to the numerator when calculating the observable + denom : str + name of the macro species that should be used as the denominator + for the observable calculation + micro_array : np.ndarray (float) + array holding concentrations of all microscopic species, calculated + elsewhere + macro_array : np.ndarray (float) + array holding concentrations of all macroscopic species, calculated + elsewhere + """ + + super().__init__(idx=idx, + expt_idx=expt_idx, + obs_key=obs_key) + + self._obs_mask = obs_mask + self._denom = denom + + self._micro_array = micro_array + self._macro_array = macro_array + + @property + def calc_value(self,*args,**kwargs): + """ + Calculate the observable given the estimated concentrations of all + species. *args and **kwargs are ignored. + """ + + num = np.sum(self._micro_array[self._idx,self._obs_mask]) + den = self._macro_array[self._idx,self._denom] + + return num/den + + +class ITCPoint(ExperimentalPoint): + """ + Class holds experimental data for an individual ITC experimental data point + and how it links to the thermodynamic model. + """ + + def __init__(self, + idx, + expt_idx, + obs_key, + dh_param_start_idx, + dh_param_end_idx, + micro_array): + """ + Initialize an ITC data point. + + Parameters + ---------- + idx : int + index of point in the experimental array + expt_idx : int + index of the experiment itself (allowing multiple experiments) + obs_key : str + key pointing to observable from the experiment + dh_param_start_idx : int + index of first enthalpy parameter in guesses array + dh_param_end_idx : int + index of last enthalpy parameter in guesses array + micro_array : np.ndarray (float) + array holding concentrations of all microscopic species, calculated + elsewhere + """ + + super().__init__(idx=idx, + expt_idx=expt_idx, + obs_key=obs_key) + + self._dh_param_start_idx = dh_param_start_idx + self._dh_param_end_idx = dh_param_end_idx + + self._micro_array = micro_array + + @property + def calc_value(self,parameters,*args,**kwargs): + """ + Calculate the heat for this shot given the current estimated + concentration changes and enthalpy parameters. *args and **kwargs are + ignored. + + Parameters + ---------- + parameters : np.ndarray (float) + fit parameters (guesses array) + """ + + dh_array = parameters[self._dh_param_start_idx:self._dh_param_end_idx] + dC = self._micro_array[self._idx,:] - self._micro_array[self._idx-1,:] + + return np.sum(dC*dh_array) \ No newline at end of file diff --git a/src/linkage/models/base.py b/src/linkage/models/base.py index 9a1d04a..d618dab 100644 --- a/src/linkage/models/base.py +++ b/src/linkage/models/base.py @@ -6,11 +6,11 @@ class BindingModel: def __init__(self): pass - def get_concs(self,K_array,C_array): + def get_concs(self,param_array,macro_array): return np.array([],dtype=float) @property - def K_names(self): + def param_names(self): return np.array(["KI","KE","K1","K2","K3","K4"]) @property @@ -18,5 +18,5 @@ def macro_species(self): return np.array(["AT","CT","ET"]) @property - def species(self): + def micro_species(self): return np.array(["I", "A", "C", "E", "AC1", "AC2", "AC3", "AC4", "EC"]) \ No newline at end of file diff --git a/src/linkage/models/six_state_edta.py b/src/linkage/models/six_state_edta.py index 2b5d78c..0655a4f 100644 --- a/src/linkage/models/six_state_edta.py +++ b/src/linkage/models/six_state_edta.py @@ -61,16 +61,16 @@ def _get_free_c(self,KI,KE,K1,K2,K3,K4,AT,CT,ET): # Return free calcium return np.real(solution[0]) - def get_concs(self,K_array,C_array): + def get_concs(self,param_array,macro_array): """ - Get the concentrations of all species in solution given the equilibrium - constants and total concentrations. + Get the concentrations of all species in solution given the model + parameters and concentrations of macro species. Parameters ---------- - K_array : numpy.ndarray + param_array : numpy.ndarray array of five equilibrium constants (KI, KE, K1, K2, K3, K4) - C_array : nump.ndarray + macro_array : nump.ndarray array of total concentrations (A_total, C_total, E_total) Returns @@ -80,8 +80,8 @@ def get_concs(self,K_array,C_array): AC3, AC4, EC). """ - KI, KE, K1, K2, K3, K4 = K_array - AT, CT, ET = C_array + KI, KE, K1, K2, K3, K4 = param_array + AT, CT, ET = macro_array # Get the free calcium concentration C = self._get_free_c(KI,KE,K1,K2,K3,K4,AT,CT,ET) @@ -112,7 +112,7 @@ def get_concs(self,K_array,C_array): return np.array([I, A, C, E, AC1, AC2, AC3, AC4, EC]) @property - def K_names(self): + def param_names(self): return np.array(["KI","KE","K1","K2","K3","K4"]) @property @@ -120,6 +120,6 @@ def macro_species(self): return np.array(["AT","CT","ET"]) @property - def species(self): + def micro_species(self): return np.array(["I", "A", "C", "E", "AC1", "AC2", "AC3", "AC4", "EC"]) diff --git a/src/linkage/organizer/__init__.py b/src/linkage/organizer/__init__.py new file mode 100644 index 0000000..01e9ea3 --- /dev/null +++ b/src/linkage/organizer/__init__.py @@ -0,0 +1 @@ +from linkage.organizer.global_fit import GlobalFit \ No newline at end of file diff --git a/src/linkage/organizer/global_fit.py b/src/linkage/organizer/global_fit.py new file mode 100644 index 0000000..474f8d2 --- /dev/null +++ b/src/linkage/organizer/global_fit.py @@ -0,0 +1,267 @@ +import linkage.models +from linkage.experiment.experimental_point import SpecPoint +from linkage.experiment.experimental_point import ITCPoint + +import numpy as np + +import copy + +class GlobalFit: + + def __init__(self,expt_list,model_name="SixStateEDTA"): + """ + Initialize a global fit. + + Parameters + ---------- + expt_list : list + list of experiments with loaded observations + model_name : str + name of model to use for the analysis + """ + + # Store model name and experiment list + self._model_name = model_name + self._expt_list = copy.deepcopy(expt_list) + + # Indexes for slicing out binding model and enthalpy parameters + self._bm_param_start_idx = None + self._bm_param_end_idx = None + self._dh_param_start_idx = None + self._dh_param_end_idx = None + + # list of all parameter names in the same order as guesses + self._all_parameter_names = [] + + # Initialize class + self._load_model() + self._sync_model_and_expt() + self._count_expt_points() + self._get_enthalpy_param() + self._process_expt_fudge() + self._build_point_map() + + + def _load_model(self): + """ + Load and initialize the thermodynamic linkage model. + """ + + # Make a list of all classes in linkage.models + available_models = {} + for k in linkage.models.__dict__: + if k.startswith("_"): + continue + + if issubclass(type(linkage.models.__dict__[k]),type): + available_models[k] = linkage.models.__dict__[k] + + # Make sure the model the user specified is found + if self._model_name not in available_models: + err = f"model_name '{self._model_name}' not recognized. It should be one of:\n" + for k in available_models: + err += f" {k}\n" + err += "\n" + raise ValueError(err) + + # Initialize binding model + self._bm = available_models[self._model_name]() + + # First binding model parameter index is 0 + self._bm_param_start_idx = 0 + + # Record names of the model parameters + for p in self._bm.param_names: + self._all_parameter_names.append(p) + + # Last binding model parameter index is last value + self._bm_param_end_idx = len(self._all_parameter_names) - 1 + + def _sync_model_and_expt(self): + """ + Make sure that all experiments have all concentrations required for the + model. + """ + + # If an experiment is missing a macro species, set the concentration of + # that molecule to 0.0 over whole titration. + for expt in self._expt_list: + not_in_expt = set(self._bm.macro_species) - set(expt.expt_concs.columns) + for missing in not_in_expt: + expt.add_expt_conc_column(new_column=missing) + + def _count_expt_points(self): + """ + Count the number of data points for a given experiment. + """ + + # Count all points for each experiment + self._points_per_expt = [] + for expt in self._expt_list: + num_obs = len(expt.observables) + num_not_ignore = np.sum(np.logical_not(expt.expt_data["ignore_point"])) + self._points_per_expt.append(num_obs*num_not_ignore) + + def _get_enthalpy_param(self): + """ + Decide if we need to include enthalpies to fit ITC data. + """ + + # Look for an ITC experiment + need_enthalpies = False + for expt in self._expt_list: + for obs in expt.observables: + if expt.observables[obs]["obs_type"] == "itc": + need_enthalpies = True + break + + # If we need enthalpies + if need_enthalpies: + + # Index of first enthalpy + self._dh_param_start_idx = len(self._all_parameter_names) + + # Names for all enthalpies + for s in self._bm.micro_species: + self._all_parameter_names.append(f"dH_{s}") + + # Last enthalpy index is last entry + self._dh_param_end_idx = len(self._all_parameter_names) - 1 + + + def _process_expt_fudge(self): + + # Fudge parameters will be last parameters in the guess list + self._fudge_list = [] + for expt_counter, expt in enumerate(self._expt_list): + + if expt.conc_to_float: + + param_name = f"expt_{expt_counter}_{expt.conc_to_float}_fudge" + self._all_parameter_names.append(param_name) + + fudge_species_index = np.where(self._bm.macro_species == expt.conc_to_float)[0][0] + fudge_value_index = len(self._all_parameter_names) - 1 + + self._fudge_list.append((fudge_species_index,fudge_value_index)) + + else: + self._fudge_list.append(None) + + def _build_point_map(self): + + # Lists of arrays that can be referenced by the individual points + self._micro_arrays = [] + self._macro_arrays = [] + + self._points = [] + self._y_obs = [] + self._y_stdev = [] + + for expt_counter, expt in enumerate(self._expt_list): + + # Each experiment will have a an array of microscopic species concentrations + self._micro_arrays.append(np.zeros((len(expt.expt_data), + len(self._bm.micro_species)), + dtype=float)) + + # ... and an array of macroscopic species concentrations + macro_array = np.array(expt.expt_concs.loc[:,self._bm.macro_species], + dtype=float) + self._macro_arrays.append(macro_array) + + for obs in expt.observables: + + obs_info = expt.observables[obs] + + for i in range(len(expt.expt_data)): + + expt_data = expt.expt_data.loc[expt.expt_data.index[i],:] + + if expt_data["ignore_point"]: + continue + + if obs_info["obs_type"] == "spec": + + pt = SpecPoint(idx=i, + expt_idx=expt_counter, + obs_key=obs, + obs_mask=np.isin(self._bm.micro_species, + obs_info["observable_species"]), + denom=obs_info["denominator"], + micro_array=self._micro_arrays[-1], + macro_array=self._macro_arrays[-1]) + + elif obs_info["obs_type"] == "itc": + + pt = ITCPoint(idx=i, + expt_idx=expt_counter, + obs_key=obs, + dh_param_start_idx=self._dh_param_start_idx, + dh_param_end_idx=self._dh_param_end_idx, + micro_array=self._micro_arrays[-1]) + + else: + obs_type = obs_info["obs_type"] + err = f"The obs type '{obs_type}' is not recognized\n" + raise ValueError(err) + + self._points.append(pt) + self._y_obs.append(expt_data[obs]) + self._y_stdev.append(self._points_per_expt[expt_counter]) + + self._y_calc = np.ones(len(self._y_obs),dtype=float)*np.nan + self._y_obs = np.array(self._y_obs) + self._y_stdev = np.array(self._y_stdev)/np.sum(self._y_stdev) + + def total_model(self,guesses): + + for i in range(len(self._macro_arrays)): + + # Figure out if we are fudging a macro array species concentration + if self._fudge_list[i] is not None: + fudge_species_index = self._fudge_list[i][0] + fudge_value = guesses[self._fudge_list[i][1]] + else: + fudge_species_index = 0 + fudge_value = 1.0 + + # For each macro concentration in this experiment + for j in range(len(self._macro_arrays[i])): + + # Build a vector with macro concentrations, possibly with one + # fudged + this_macro_array = self._macro_arrays[i][j,:] + this_macro_array[fudge_species_index] *= fudge_value + + # Grab parameters from guesses + this_param_array = guesses[self._bm_param_start_idx:self._bm_param_end_idx+1] + + # Update microscopic species concentrations + self._micro_arrays[i][j,:] = self._bm.get_concs(param_array=this_param_array, + macro_array=this_macro_array) + + # For each point, calculate the observable + for i in range(len(self._points)): + self._y_calc[i] = self._points[i].calc_value(guesses) + + return self._y_calc + + @property + def y_calc(self): + return self._y_calc + + @property + def y_obs(self): + return self._y_obs + + @property + def y_stdev(self): + return self._y_stdev + + @property + def parameter_names(self): + return self._all_parameter_names + + + \ No newline at end of file diff --git a/tests/linkage/experiment/test_titrator.py b/tests/linkage/experiment/test_titrator.py new file mode 100644 index 0000000..7ba7f80 --- /dev/null +++ b/tests/linkage/experiment/test_titrator.py @@ -0,0 +1,21 @@ +import pytest +import numpy as np +import pandas as pd + +from linkage.experiment.titrator import titrator + +import copy + +def test_titrator(): + + base_kwargs = {"cell_contents":{"X":0,"Y":10}, + "syringe_contents":{"X":10,"Y":10}, + "cell_volume":100, + "injection_array":np.ones(10,dtype=float), + "constant_volume":False} + + kwargs = copy.deepcopy(base_kwargs) + df = titrator(**kwargs) + assert issubclass(type(df),pd.DataFrame) + + From 003dce847531a0b24bf9d5bb0880f1f1c5d86a5f Mon Sep 17 00:00:00 2001 From: Michael Harms Date: Tue, 23 Jul 2024 16:18:06 -0700 Subject: [PATCH 02/17] intermediate commit; fit now working without error --- docs/badges/coverage-badge.svg | 2 +- docs/badges/tests-badge.svg | 2 +- reports/flake.txt | 337 +++++++++++-------- reports/junit/junit.xml | 2 +- src/linkage/experiment/experimental_point.py | 6 +- src/linkage/organizer/global_fit.py | 19 +- tests/{linkage => }/conftest.py | 40 +++ tests/linkage/organizer/test_global_fit.py | 21 ++ 8 files changed, 270 insertions(+), 159 deletions(-) rename tests/{linkage => }/conftest.py (70%) create mode 100644 tests/linkage/organizer/test_global_fit.py diff --git a/docs/badges/coverage-badge.svg b/docs/badges/coverage-badge.svg index c75c126..d03b755 100644 --- a/docs/badges/coverage-badge.svg +++ b/docs/badges/coverage-badge.svg @@ -1 +1 @@ -coverage: 29.51%coverage29.51% \ No newline at end of file +coverage: 51.14%coverage51.14% \ No newline at end of file diff --git a/docs/badges/tests-badge.svg b/docs/badges/tests-badge.svg index a9cdf90..e27c830 100644 --- a/docs/badges/tests-badge.svg +++ b/docs/badges/tests-badge.svg @@ -1 +1 @@ -tests: 1tests1 \ No newline at end of file +tests: 2tests2 \ No newline at end of file diff --git a/reports/flake.txt b/reports/flake.txt index a27e304..3747288 100644 --- a/reports/flake.txt +++ b/reports/flake.txt @@ -69,25 +69,25 @@ ./build/lib/linkage/experiment/experimental_point.py:86:1: W293 blank line contains whitespace ./build/lib/linkage/experiment/experimental_point.py:89:1: W293 blank line contains whitespace ./build/lib/linkage/experiment/experimental_point.py:92:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:94:24: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:94:30: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:96:75: W291 trailing whitespace -./build/lib/linkage/experiment/experimental_point.py:100:49: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:101:42: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:109:49: W291 trailing whitespace -./build/lib/linkage/experiment/experimental_point.py:120:38: W291 trailing whitespace -./build/lib/linkage/experiment/experimental_point.py:121:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:142:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:145:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:147:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:149:24: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:149:35: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:149:41: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:153:17: W291 trailing whitespace -./build/lib/linkage/experiment/experimental_point.py:162:41: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:162:76: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:163:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:164:35: W292 no newline at end of file +./build/lib/linkage/experiment/experimental_point.py:93:24: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:93:30: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:95:75: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:99:49: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:100:42: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:108:49: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:119:38: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:120:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:141:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:144:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:146:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:147:24: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:147:35: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:147:41: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:151:17: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:160:41: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:160:76: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:161:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:162:35: W292 no newline at end of file ./build/lib/linkage/experiment/titrator.py:6:1: E302 expected 2 blank lines, found 1 ./build/lib/linkage/experiment/titrator.py:13:55: W291 trailing whitespace ./build/lib/linkage/experiment/titrator.py:14:1: W293 blank line contains whitespace @@ -194,9 +194,7 @@ ./build/lib/linkage/organizer/global_fit.py:11:22: E231 missing whitespace after ',' ./build/lib/linkage/organizer/global_fit.py:11:32: E231 missing whitespace after ',' ./build/lib/linkage/organizer/global_fit.py:14:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:35:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:44:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:45:5: E303 too many blank lines (2) +./build/lib/linkage/organizer/global_fit.py:36:1: W293 blank line contains whitespace ./build/lib/linkage/organizer/global_fit.py:47:61: W291 trailing whitespace ./build/lib/linkage/organizer/global_fit.py:49:1: W293 blank line contains whitespace ./build/lib/linkage/organizer/global_fit.py:55:1: W293 blank line contains whitespace @@ -205,53 +203,54 @@ ./build/lib/linkage/organizer/global_fit.py:59:58: W291 trailing whitespace ./build/lib/linkage/organizer/global_fit.py:66:1: W293 blank line contains whitespace ./build/lib/linkage/organizer/global_fit.py:72:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:79:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:83:15: W291 trailing whitespace -./build/lib/linkage/organizer/global_fit.py:85:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:87:53: W291 trailing whitespace -./build/lib/linkage/organizer/global_fit.py:97:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:98:47: W291 trailing whitespace -./build/lib/linkage/organizer/global_fit.py:113:41: W291 trailing whitespace -./build/lib/linkage/organizer/global_fit.py:120:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:123:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:130:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:132:5: E303 too many blank lines (2) -./build/lib/linkage/organizer/global_fit.py:134:69: W291 trailing whitespace -./build/lib/linkage/organizer/global_fit.py:137:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:142:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:80:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:84:15: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:86:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:88:53: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:98:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:99:47: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:114:41: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:121:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:124:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:132:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:134:5: E303 too many blank lines (2) +./build/lib/linkage/organizer/global_fit.py:136:69: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:139:1: W293 blank line contains whitespace ./build/lib/linkage/organizer/global_fit.py:145:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:146:61: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_fit.py:147:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:148:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:149:61: E231 missing whitespace after ',' ./build/lib/linkage/organizer/global_fit.py:150:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:160:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:169:57: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_fit.py:172:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:174:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:176:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:178:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:179:75: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_fit.py:180:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:153:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:163:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:172:57: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:175:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:177:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:179:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:181:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:182:75: E231 missing whitespace after ',' ./build/lib/linkage/organizer/global_fit.py:183:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:194:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:196:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:203:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:186:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:199:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:201:1: W293 blank line contains whitespace ./build/lib/linkage/organizer/global_fit.py:208:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:213:48: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_fit.py:216:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:217:25: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_fit.py:218:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:220:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:226:17: F841 local variable 'fudge_species_index' is assigned to but never used -./build/lib/linkage/organizer/global_fit.py:232:78: W291 trailing whitespace -./build/lib/linkage/organizer/global_fit.py:234:59: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_fit.py:235:34: F821 undefined name 'fudge_index' -./build/lib/linkage/organizer/global_fit.py:241:40: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_fit.py:247:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:213:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:218:48: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:222:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:223:5: E303 too many blank lines (2) +./build/lib/linkage/organizer/global_fit.py:223:25: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:224:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:226:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:238:78: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:240:59: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:243:48: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:244:53: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:247:40: E231 missing whitespace after ',' ./build/lib/linkage/organizer/global_fit.py:253:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:265:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:266:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:267:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:267:9: W292 no newline at end of file +./build/lib/linkage/organizer/global_fit.py:259:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:271:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:275:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:276:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:276:9: W292 no newline at end of file ./src/linkage/__init__.py:2:1: F401 'linkage.experiment.Experiment' imported but unused ./src/linkage/__init__.py:3:1: F401 'linkage.organizer.GlobalFit' imported but unused ./src/linkage/__init__.py:12:52: E231 missing whitespace after ',' @@ -316,25 +315,25 @@ ./src/linkage/experiment/experimental_point.py:86:1: W293 blank line contains whitespace ./src/linkage/experiment/experimental_point.py:89:1: W293 blank line contains whitespace ./src/linkage/experiment/experimental_point.py:92:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:94:24: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:94:30: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:96:75: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:100:49: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:101:42: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:109:49: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:120:38: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:121:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:142:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:145:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:147:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:149:24: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:149:35: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:149:41: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:153:17: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:162:41: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:162:76: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:163:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:164:35: W292 no newline at end of file +./src/linkage/experiment/experimental_point.py:93:24: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:93:30: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:95:75: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:99:49: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:100:42: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:108:49: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:119:38: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:120:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:141:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:144:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:146:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:147:24: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:147:35: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:147:41: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:151:17: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:160:41: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:160:76: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:161:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:162:35: W292 no newline at end of file ./src/linkage/experiment/titrator.py:6:1: E302 expected 2 blank lines, found 1 ./src/linkage/experiment/titrator.py:13:55: W291 trailing whitespace ./src/linkage/experiment/titrator.py:14:1: W293 blank line contains whitespace @@ -441,9 +440,7 @@ ./src/linkage/organizer/global_fit.py:11:22: E231 missing whitespace after ',' ./src/linkage/organizer/global_fit.py:11:32: E231 missing whitespace after ',' ./src/linkage/organizer/global_fit.py:14:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:35:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:44:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:45:5: E303 too many blank lines (2) +./src/linkage/organizer/global_fit.py:36:1: W293 blank line contains whitespace ./src/linkage/organizer/global_fit.py:47:61: W291 trailing whitespace ./src/linkage/organizer/global_fit.py:49:1: W293 blank line contains whitespace ./src/linkage/organizer/global_fit.py:55:1: W293 blank line contains whitespace @@ -452,62 +449,101 @@ ./src/linkage/organizer/global_fit.py:59:58: W291 trailing whitespace ./src/linkage/organizer/global_fit.py:66:1: W293 blank line contains whitespace ./src/linkage/organizer/global_fit.py:72:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:79:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:83:15: W291 trailing whitespace -./src/linkage/organizer/global_fit.py:85:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:87:53: W291 trailing whitespace -./src/linkage/organizer/global_fit.py:97:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:98:47: W291 trailing whitespace -./src/linkage/organizer/global_fit.py:113:41: W291 trailing whitespace -./src/linkage/organizer/global_fit.py:120:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:123:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:130:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:132:5: E303 too many blank lines (2) -./src/linkage/organizer/global_fit.py:134:69: W291 trailing whitespace -./src/linkage/organizer/global_fit.py:137:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:142:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:80:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:84:15: W291 trailing whitespace +./src/linkage/organizer/global_fit.py:86:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:88:53: W291 trailing whitespace +./src/linkage/organizer/global_fit.py:98:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:99:47: W291 trailing whitespace +./src/linkage/organizer/global_fit.py:114:41: W291 trailing whitespace +./src/linkage/organizer/global_fit.py:121:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:124:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:132:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:134:5: E303 too many blank lines (2) +./src/linkage/organizer/global_fit.py:136:69: W291 trailing whitespace +./src/linkage/organizer/global_fit.py:139:1: W293 blank line contains whitespace ./src/linkage/organizer/global_fit.py:145:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:146:61: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:147:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:148:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:149:61: E231 missing whitespace after ',' ./src/linkage/organizer/global_fit.py:150:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:160:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:169:57: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:172:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:174:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:176:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:178:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:179:75: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:180:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:153:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:163:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:172:57: E231 missing whitespace after ',' +./src/linkage/organizer/global_fit.py:175:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:177:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:179:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:181:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:182:75: E231 missing whitespace after ',' ./src/linkage/organizer/global_fit.py:183:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:194:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:196:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:203:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:186:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:199:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:201:1: W293 blank line contains whitespace ./src/linkage/organizer/global_fit.py:208:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:213:48: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:216:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:217:25: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:218:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:220:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:232:78: W291 trailing whitespace -./src/linkage/organizer/global_fit.py:234:59: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:241:40: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:247:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:213:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:218:48: E231 missing whitespace after ',' +./src/linkage/organizer/global_fit.py:222:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:223:5: E303 too many blank lines (2) +./src/linkage/organizer/global_fit.py:223:25: E231 missing whitespace after ',' +./src/linkage/organizer/global_fit.py:224:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:226:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:238:78: W291 trailing whitespace +./src/linkage/organizer/global_fit.py:240:59: E231 missing whitespace after ',' +./src/linkage/organizer/global_fit.py:243:48: W291 trailing whitespace +./src/linkage/organizer/global_fit.py:244:53: E231 missing whitespace after ',' +./src/linkage/organizer/global_fit.py:247:40: E231 missing whitespace after ',' ./src/linkage/organizer/global_fit.py:253:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:265:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:266:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:267:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:267:9: W292 no newline at end of file -./tests/linkage/conftest.py:5:1: E302 expected 2 blank lines, found 1 -./tests/linkage/conftest.py:36:63: E231 missing whitespace after ',' -./tests/linkage/conftest.py:50:49: E231 missing whitespace after ',' -./tests/linkage/conftest.py:56:9: F841 local variable 'patterns' is assigned to but never used -./tests/linkage/conftest.py:61:68: E231 missing whitespace after ',' -./tests/linkage/conftest.py:66:64: E231 missing whitespace after ',' -./tests/linkage/conftest.py:66:65: F541 f-string is missing placeholders -./tests/linkage/conftest.py:73:58: E231 missing whitespace after ',' -./tests/linkage/conftest.py:77:58: E231 missing whitespace after ',' -./tests/linkage/conftest.py:87:1: E302 expected 2 blank lines, found 1 -./tests/linkage/conftest.py:89:41: E231 missing whitespace after ',' +./src/linkage/organizer/global_fit.py:259:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:271:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:275:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:276:1: W293 blank line contains whitespace +./src/linkage/organizer/global_fit.py:276:9: W292 no newline at end of file +./tests/conftest.py:11:1: E302 expected 2 blank lines, found 1 +./tests/conftest.py:42:63: E231 missing whitespace after ',' +./tests/conftest.py:56:49: E231 missing whitespace after ',' +./tests/conftest.py:62:9: F841 local variable 'patterns' is assigned to but never used +./tests/conftest.py:67:68: E231 missing whitespace after ',' +./tests/conftest.py:72:64: E231 missing whitespace after ',' +./tests/conftest.py:72:65: F541 f-string is missing placeholders +./tests/conftest.py:79:58: E231 missing whitespace after ',' +./tests/conftest.py:83:58: E231 missing whitespace after ',' +./tests/conftest.py:93:1: E302 expected 2 blank lines, found 1 +./tests/conftest.py:95:41: E231 missing whitespace after ',' +./tests/conftest.py:97:1: E302 expected 2 blank lines, found 1 +./tests/conftest.py:101:42: E231 missing whitespace after ':' +./tests/conftest.py:102:29: E128 continuation line under-indented for visual indent +./tests/conftest.py:102:36: E231 missing whitespace after ':' +./tests/conftest.py:102:55: E231 missing whitespace after ',' +./tests/conftest.py:102:57: E231 missing whitespace after ',' +./tests/conftest.py:103:29: E128 continuation line under-indented for visual indent +./tests/conftest.py:103:36: E231 missing whitespace after ':' +./tests/conftest.py:103:55: E231 missing whitespace after ',' +./tests/conftest.py:103:57: E231 missing whitespace after ',' +./tests/conftest.py:104:37: E231 missing whitespace after ',' +./tests/conftest.py:106:41: E231 missing whitespace after ':' +./tests/conftest.py:107:35: E231 missing whitespace after ':' +./tests/conftest.py:107:54: E231 missing whitespace after ',' +./tests/conftest.py:107:56: E231 missing whitespace after ',' +./tests/conftest.py:110:5: E303 too many blank lines (2) +./tests/conftest.py:112:37: E128 continuation line under-indented for visual indent +./tests/conftest.py:112:56: E231 missing whitespace after ':' +./tests/conftest.py:113:53: E127 continuation line over-indented for visual indent +./tests/conftest.py:113:57: E231 missing whitespace after ':' +./tests/conftest.py:114:37: E128 continuation line under-indented for visual indent +./tests/conftest.py:114:59: E231 missing whitespace after ':' +./tests/conftest.py:115:37: E128 continuation line under-indented for visual indent +./tests/conftest.py:117:29: E231 missing whitespace after ',' +./tests/conftest.py:117:36: E231 missing whitespace after ',' +./tests/conftest.py:117:59: E231 missing whitespace after ',' +./tests/conftest.py:118:29: E231 missing whitespace after ',' +./tests/conftest.py:118:36: E231 missing whitespace after ',' +./tests/conftest.py:118:60: E231 missing whitespace after ',' +./tests/conftest.py:118:65: E231 missing whitespace after ',' +./tests/conftest.py:122:17: E128 continuation line under-indented for visual indent +./tests/conftest.py:122:36: E231 missing whitespace after ':' +./tests/conftest.py:123:39: E231 missing whitespace after ':' +./tests/conftest.py:125:28: E231 missing whitespace after ',' +./tests/conftest.py:127:19: E231 missing whitespace after ',' +./tests/conftest.py:129:21: W292 no newline at end of file ./tests/linkage/experiment/test_titrator.py:1:1: F401 'pytest' imported but unused ./tests/linkage/experiment/test_titrator.py:9:1: E302 expected 2 blank lines, found 1 ./tests/linkage/experiment/test_titrator.py:10:1: W293 blank line contains whitespace @@ -526,17 +562,24 @@ ./tests/linkage/experiment/test_titrator.py:16:1: W293 blank line contains whitespace ./tests/linkage/experiment/test_titrator.py:19:31: E231 missing whitespace after ',' ./tests/linkage/experiment/test_titrator.py:21:1: W391 blank line at end of file +./tests/linkage/organizer/test_global_fit.py:3:1: F401 'pytest' imported but unused +./tests/linkage/organizer/test_global_fit.py:5:1: F401 'linkage' imported but unused +./tests/linkage/organizer/test_global_fit.py:8:1: F401 'numpy as np' imported but unused +./tests/linkage/organizer/test_global_fit.py:11:1: E302 expected 2 blank lines, found 1 +./tests/linkage/organizer/test_global_fit.py:16:5: E303 too many blank lines (2) +./tests/linkage/organizer/test_global_fit.py:20:1: W293 blank line contains whitespace +1 E127 continuation line over-indented for visual indent +6 E128 continuation line under-indented for visual indent 6 E225 missing whitespace around operator -214 E231 missing whitespace after ',' -18 E302 expected 2 blank lines, found 1 -6 E303 too many blank lines (3) +242 E231 missing whitespace after ',' +20 E302 expected 2 blank lines, found 1 +8 E303 too many blank lines (3) 2 E741 ambiguous variable name 'I' -12 F401 'linkage.experiment.Experiment' imported but unused +15 F401 'linkage.experiment.Experiment' imported but unused 1 F541 f-string is missing placeholders -1 F821 undefined name 'fudge_index' -3 F841 local variable 'args' is assigned to but never used -64 W291 trailing whitespace -11 W292 no newline at end of file -187 W293 blank line contains whitespace +2 F841 local variable 'args' is assigned to but never used +66 W291 trailing whitespace +12 W292 no newline at end of file +186 W293 blank line contains whitespace 3 W391 blank line at end of file -528 +570 diff --git a/reports/junit/junit.xml b/reports/junit/junit.xml index 1542c1f..b807fc5 100644 --- a/reports/junit/junit.xml +++ b/reports/junit/junit.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/linkage/experiment/experimental_point.py b/src/linkage/experiment/experimental_point.py index 1d36dbf..9382260 100644 --- a/src/linkage/experiment/experimental_point.py +++ b/src/linkage/experiment/experimental_point.py @@ -69,8 +69,8 @@ def __init__(self, obs_mask : np.ndarray (bool or int) mask that grabs microscopic species from micro_array that correspond to the numerator when calculating the observable - denom : str - name of the macro species that should be used as the denominator + denom : int + index of the macro species that should be used as the denominator for the observable calculation micro_array : np.ndarray (float) array holding concentrations of all microscopic species, calculated @@ -90,7 +90,6 @@ def __init__(self, self._micro_array = micro_array self._macro_array = macro_array - @property def calc_value(self,*args,**kwargs): """ Calculate the observable given the estimated concentrations of all @@ -145,7 +144,6 @@ def __init__(self, self._micro_array = micro_array - @property def calc_value(self,parameters,*args,**kwargs): """ Calculate the heat for this shot given the current estimated diff --git a/src/linkage/organizer/global_fit.py b/src/linkage/organizer/global_fit.py index 474f8d2..8271bc8 100644 --- a/src/linkage/organizer/global_fit.py +++ b/src/linkage/organizer/global_fit.py @@ -32,6 +32,7 @@ def __init__(self,expt_list,model_name="SixStateEDTA"): # list of all parameter names in the same order as guesses self._all_parameter_names = [] + self._parameter_guesses = [] # Initialize class self._load_model() @@ -41,7 +42,6 @@ def __init__(self,expt_list,model_name="SixStateEDTA"): self._process_expt_fudge() self._build_point_map() - def _load_model(self): """ Load and initialize the thermodynamic linkage model. @@ -73,6 +73,7 @@ def _load_model(self): # Record names of the model parameters for p in self._bm.param_names: self._all_parameter_names.append(p) + self._parameter_guesses.append(0.0) # Last binding model parameter index is last value self._bm_param_end_idx = len(self._all_parameter_names) - 1 @@ -124,6 +125,7 @@ def _get_enthalpy_param(self): # Names for all enthalpies for s in self._bm.micro_species: self._all_parameter_names.append(f"dH_{s}") + self._parameter_guesses.append(0.0) # Last enthalpy index is last entry self._dh_param_end_idx = len(self._all_parameter_names) - 1 @@ -139,6 +141,7 @@ def _process_expt_fudge(self): param_name = f"expt_{expt_counter}_{expt.conc_to_float}_fudge" self._all_parameter_names.append(param_name) + self._parameter_guesses.append(1.0) fudge_species_index = np.where(self._bm.macro_species == expt.conc_to_float)[0][0] fudge_value_index = len(self._all_parameter_names) - 1 @@ -183,12 +186,14 @@ def _build_point_map(self): if obs_info["obs_type"] == "spec": + den_index = np.where(self._bm.macro_species == obs_info["denominator"])[0][0] + pt = SpecPoint(idx=i, expt_idx=expt_counter, obs_key=obs, obs_mask=np.isin(self._bm.micro_species, obs_info["observable_species"]), - denom=obs_info["denominator"], + denom=den_index, micro_array=self._micro_arrays[-1], macro_array=self._macro_arrays[-1]) @@ -198,7 +203,7 @@ def _build_point_map(self): expt_idx=expt_counter, obs_key=obs, dh_param_start_idx=self._dh_param_start_idx, - dh_param_end_idx=self._dh_param_end_idx, + dh_param_end_idx=self._dh_param_end_idx + 1, micro_array=self._micro_arrays[-1]) else: @@ -213,6 +218,7 @@ def _build_point_map(self): self._y_calc = np.ones(len(self._y_obs),dtype=float)*np.nan self._y_obs = np.array(self._y_obs) self._y_stdev = np.array(self._y_stdev)/np.sum(self._y_stdev) + def total_model(self,guesses): @@ -234,8 +240,8 @@ def total_model(self,guesses): this_macro_array = self._macro_arrays[i][j,:] this_macro_array[fudge_species_index] *= fudge_value - # Grab parameters from guesses - this_param_array = guesses[self._bm_param_start_idx:self._bm_param_end_idx+1] + # Grab parameters from guesses. + this_param_array = np.float_power(10,guesses[self._bm_param_start_idx:self._bm_param_end_idx+1]) # Update microscopic species concentrations self._micro_arrays[i][j,:] = self._bm.get_concs(param_array=this_param_array, @@ -263,5 +269,8 @@ def y_stdev(self): def parameter_names(self): return self._all_parameter_names + @property + def parameter_guesses(self): + return self._parameter_guesses \ No newline at end of file diff --git a/tests/linkage/conftest.py b/tests/conftest.py similarity index 70% rename from tests/linkage/conftest.py rename to tests/conftest.py index af686e3..79cd60e 100644 --- a/tests/linkage/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,10 @@ import pytest + +import linkage + +import pandas as pd +import numpy as np + import os import glob @@ -87,3 +93,37 @@ def get_files(base_dir): @pytest.fixture(scope="module") def example_xyz(): return get_files(os.path.join("data","example-xyz")) + +@pytest.fixture(scope="module") +def fake_spec_and_itc_data(): + + # Fake data + expt_data = pd.DataFrame({"injection":25*np.ones(50), + "cd222":np.random.normal(0,1,50), + "cd240":np.random.normal(0,1,50)}) + expt_data.loc[expt_data.index[0],"injection"] = 0.0 + + itc_data = pd.DataFrame({"injection":25*np.ones(50), + "heat":np.random.normal(0,1,50)}) + + + # Load spec data + e = linkage.experiment.Experiment(expt_data, + cell_contents={"AT":50e-6, + "CT":0.5e-3}, + syringe_contents={"ET":1e-3}, + conc_to_float="AT") + + e.add_observable("cd222","spec",observable_species="I",denominator="AT") + e.add_observable("cd240","spec",observable_species=["I","A"],denominator="AT") + + # Load ITC data + f = linkage.experiment.Experiment(itc_data, + cell_contents={"CT":0.5e-3}, + syringe_contents={"ET":1e-3}, + conc_to_float=None) + f.add_observable("heat","itc") + + expt_list = [e,f] + + return expt_list \ No newline at end of file diff --git a/tests/linkage/organizer/test_global_fit.py b/tests/linkage/organizer/test_global_fit.py new file mode 100644 index 0000000..c77ff17 --- /dev/null +++ b/tests/linkage/organizer/test_global_fit.py @@ -0,0 +1,21 @@ + + +import pytest + +import linkage +from linkage.organizer.global_fit import GlobalFit + +import numpy as np +import copy + +def test_GlobalFit_integrated(fake_spec_and_itc_data): + + base_expt_list = copy.deepcopy(fake_spec_and_itc_data) + + + this_expt_list = copy.deepcopy(base_expt_list) + + gf = GlobalFit(model_name="SixStateEDTA", + expt_list=this_expt_list) + + gf.total_model(gf.parameter_guesses) From 951a538dc070b1568ebe4a7928b89fe094f7e321 Mon Sep 17 00:00:00 2001 From: Michael Harms Date: Tue, 23 Jul 2024 20:23:20 -0700 Subject: [PATCH 03/17] added tests for GlobalModel --- docs/badges/coverage-badge.svg | 2 +- docs/badges/tests-badge.svg | 2 +- reports/flake.txt | 540 +++++++++++------- reports/junit/junit.xml | 2 +- src/linkage/__init__.py | 2 +- src/linkage/experiment/experimental_point.py | 52 +- src/linkage/organizer/__init__.py | 2 +- .../{global_fit.py => global_model.py} | 85 ++- tests/linkage/organizer/test_global_fit.py | 21 - tests/linkage/organizer/test_global_model.py | 177 ++++++ 10 files changed, 630 insertions(+), 255 deletions(-) rename src/linkage/organizer/{global_fit.py => global_model.py} (81%) delete mode 100644 tests/linkage/organizer/test_global_fit.py create mode 100644 tests/linkage/organizer/test_global_model.py diff --git a/docs/badges/coverage-badge.svg b/docs/badges/coverage-badge.svg index d03b755..34601e6 100644 --- a/docs/badges/coverage-badge.svg +++ b/docs/badges/coverage-badge.svg @@ -1 +1 @@ -coverage: 51.14%coverage51.14% \ No newline at end of file +coverage: 77.01%coverage77.01% \ No newline at end of file diff --git a/docs/badges/tests-badge.svg b/docs/badges/tests-badge.svg index e27c830..fe9b4a3 100644 --- a/docs/badges/tests-badge.svg +++ b/docs/badges/tests-badge.svg @@ -1 +1 @@ -tests: 2tests2 \ No newline at end of file +tests: 8tests8 \ No newline at end of file diff --git a/reports/flake.txt b/reports/flake.txt index 3747288..26af4c3 100644 --- a/reports/flake.txt +++ b/reports/flake.txt @@ -1,5 +1,5 @@ ./build/lib/linkage/__init__.py:2:1: F401 'linkage.experiment.Experiment' imported but unused -./build/lib/linkage/__init__.py:3:1: F401 'linkage.organizer.GlobalFit' imported but unused +./build/lib/linkage/__init__.py:3:1: F401 'linkage.organizer.GlobalModel' imported but unused ./build/lib/linkage/__init__.py:12:52: E231 missing whitespace after ',' ./build/lib/linkage/__init__.py:13:36: W292 no newline at end of file ./build/lib/linkage/cli.py:2:1: F401 'linkage' imported but unused @@ -59,35 +59,36 @@ ./build/lib/linkage/experiment/experimental_point.py:3:1: E302 expected 2 blank lines, found 1 ./build/lib/linkage/experiment/experimental_point.py:6:13: W291 trailing whitespace ./build/lib/linkage/experiment/experimental_point.py:8:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:16:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:34:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:44:1: E303 too many blank lines (3) -./build/lib/linkage/experiment/experimental_point.py:46:66: W291 trailing whitespace -./build/lib/linkage/experiment/experimental_point.py:47:67: W291 trailing whitespace -./build/lib/linkage/experiment/experimental_point.py:59:47: W291 trailing whitespace -./build/lib/linkage/experiment/experimental_point.py:60:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:86:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:89:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:18:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:38:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:48:1: E303 too many blank lines (3) +./build/lib/linkage/experiment/experimental_point.py:50:66: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:51:67: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:63:47: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:64:1: W293 blank line contains whitespace ./build/lib/linkage/experiment/experimental_point.py:92:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:93:24: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:93:30: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:95:75: W291 trailing whitespace -./build/lib/linkage/experiment/experimental_point.py:99:49: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:100:42: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:108:49: W291 trailing whitespace -./build/lib/linkage/experiment/experimental_point.py:119:38: W291 trailing whitespace -./build/lib/linkage/experiment/experimental_point.py:120:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:141:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:95:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:96:24: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:96:30: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:98:75: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:102:49: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:103:42: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:111:49: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:123:38: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:124:1: W293 blank line contains whitespace ./build/lib/linkage/experiment/experimental_point.py:144:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:146:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:147:24: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:147:35: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:147:41: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:151:17: W291 trailing whitespace -./build/lib/linkage/experiment/experimental_point.py:160:41: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:160:76: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:161:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:162:35: W292 no newline at end of file +./build/lib/linkage/experiment/experimental_point.py:150:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:153:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:154:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:155:5: E303 too many blank lines (2) +./build/lib/linkage/experiment/experimental_point.py:155:24: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:155:35: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:155:41: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:159:17: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:168:41: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:168:76: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:169:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:170:35: W292 no newline at end of file ./build/lib/linkage/experiment/titrator.py:6:1: E302 expected 2 blank lines, found 1 ./build/lib/linkage/experiment/titrator.py:13:55: W291 trailing whitespace ./build/lib/linkage/experiment/titrator.py:14:1: W293 blank line contains whitespace @@ -188,71 +189,160 @@ ./build/lib/linkage/models/six_state_edta.py:120:35: E231 missing whitespace after ',' ./build/lib/linkage/models/six_state_edta.py:121:1: W293 blank line contains whitespace ./build/lib/linkage/models/six_state_edta.py:125:1: W391 blank line at end of file -./build/lib/linkage/organizer/__init__.py:1:1: F401 'linkage.organizer.global_fit.GlobalFit' imported but unused -./build/lib/linkage/organizer/__init__.py:1:51: W292 no newline at end of file -./build/lib/linkage/organizer/global_fit.py:9:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/organizer/global_fit.py:11:22: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_fit.py:11:32: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_fit.py:14:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:36:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:47:61: W291 trailing whitespace -./build/lib/linkage/organizer/global_fit.py:49:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:55:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:56:59: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_fit.py:58:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:59:58: W291 trailing whitespace -./build/lib/linkage/organizer/global_fit.py:66:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:72:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:80:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:84:15: W291 trailing whitespace -./build/lib/linkage/organizer/global_fit.py:86:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:88:53: W291 trailing whitespace -./build/lib/linkage/organizer/global_fit.py:98:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:99:47: W291 trailing whitespace -./build/lib/linkage/organizer/global_fit.py:114:41: W291 trailing whitespace -./build/lib/linkage/organizer/global_fit.py:121:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:124:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:132:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:134:5: E303 too many blank lines (2) -./build/lib/linkage/organizer/global_fit.py:136:69: W291 trailing whitespace -./build/lib/linkage/organizer/global_fit.py:139:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:145:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:148:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:149:61: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_fit.py:150:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:153:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:163:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:172:57: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_fit.py:175:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:177:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:179:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:181:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:182:75: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_fit.py:183:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:186:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:199:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:201:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:208:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:213:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:218:48: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_fit.py:222:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:223:5: E303 too many blank lines (2) -./build/lib/linkage/organizer/global_fit.py:223:25: E231 missing whitespace after ',' +./build/lib/linkage/organizer/__init__.py:1:1: F401 'linkage.organizer.global_model.GlobalModel' imported but unused +./build/lib/linkage/organizer/__init__.py:1:55: W292 no newline at end of file +./build/lib/linkage/organizer/global_fit.py:10:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/organizer/global_fit.py:12:22: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:12:32: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:15:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:37:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:48:61: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:50:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:56:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:57:59: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:59:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:60:58: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:67:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:73:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:81:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:85:15: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:87:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:89:53: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:99:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:100:47: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:115:41: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:122:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:125:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:133:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:135:5: E303 too many blank lines (2) +./build/lib/linkage/organizer/global_fit.py:137:69: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:140:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:146:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:149:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:150:61: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:151:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:154:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:164:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:173:57: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:176:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:178:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:180:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:182:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:183:75: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:184:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:187:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:200:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:202:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:210:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:215:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:220:48: E231 missing whitespace after ',' ./build/lib/linkage/organizer/global_fit.py:224:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:225:5: E303 too many blank lines (2) +./build/lib/linkage/organizer/global_fit.py:225:19: E231 missing whitespace after ',' ./build/lib/linkage/organizer/global_fit.py:226:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:238:78: W291 trailing whitespace -./build/lib/linkage/organizer/global_fit.py:240:59: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_fit.py:243:48: W291 trailing whitespace -./build/lib/linkage/organizer/global_fit.py:244:53: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_fit.py:247:40: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_fit.py:253:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:259:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:271:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:229:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:241:78: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:243:59: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:246:56: W291 trailing whitespace +./build/lib/linkage/organizer/global_fit.py:247:53: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:250:40: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:257:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:263:1: W293 blank line contains whitespace ./build/lib/linkage/organizer/global_fit.py:275:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:276:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_fit.py:276:9: W292 no newline at end of file +./build/lib/linkage/organizer/global_fit.py:279:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:283:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:287:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:291:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:295:25: E231 missing whitespace after ':' +./build/lib/linkage/organizer/global_fit.py:296:27: E231 missing whitespace after ':' +./build/lib/linkage/organizer/global_fit.py:297:26: E231 missing whitespace after ':' +./build/lib/linkage/organizer/global_fit.py:306:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:309:34: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:315:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:316:36: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:326:52: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:329:52: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_fit.py:330:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:337:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_fit.py:337:9: W292 no newline at end of file +./build/lib/linkage/organizer/global_model.py:10:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/organizer/global_model.py:12:22: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:12:32: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:15:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:37:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:48:61: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:50:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:56:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:57:59: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:59:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:60:58: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:67:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:73:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:81:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:85:15: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:87:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:89:53: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:99:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:100:47: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:115:41: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:122:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:125:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:133:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:135:5: E303 too many blank lines (2) +./build/lib/linkage/organizer/global_model.py:137:69: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:140:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:146:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:149:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:150:61: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:151:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:154:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:164:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:169:49: E127 continuation line over-indented for visual indent +./build/lib/linkage/organizer/global_model.py:170:48: E127 continuation line over-indented for visual indent +./build/lib/linkage/organizer/global_model.py:173:57: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:176:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:178:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:180:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:182:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:183:75: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:184:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:187:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:200:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:202:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:210:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:215:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:220:48: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:224:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:225:5: E303 too many blank lines (2) +./build/lib/linkage/organizer/global_model.py:225:19: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:226:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:229:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:241:78: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:243:59: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:246:56: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:247:53: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:250:40: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:257:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:263:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:275:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:279:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:283:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:287:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:291:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:295:25: E231 missing whitespace after ':' +./build/lib/linkage/organizer/global_model.py:296:27: E231 missing whitespace after ':' +./build/lib/linkage/organizer/global_model.py:297:26: E231 missing whitespace after ':' +./build/lib/linkage/organizer/global_model.py:306:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:309:34: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:315:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:316:36: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:326:52: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:329:52: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:330:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:337:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:337:9: W292 no newline at end of file ./src/linkage/__init__.py:2:1: F401 'linkage.experiment.Experiment' imported but unused -./src/linkage/__init__.py:3:1: F401 'linkage.organizer.GlobalFit' imported but unused +./src/linkage/__init__.py:3:1: F401 'linkage.organizer.GlobalModel' imported but unused ./src/linkage/__init__.py:12:52: E231 missing whitespace after ',' ./src/linkage/__init__.py:13:36: W292 no newline at end of file ./src/linkage/experiment/__init__.py:2:1: F401 'linkage.experiment.experiment.Experiment' imported but unused @@ -305,35 +395,36 @@ ./src/linkage/experiment/experimental_point.py:3:1: E302 expected 2 blank lines, found 1 ./src/linkage/experiment/experimental_point.py:6:13: W291 trailing whitespace ./src/linkage/experiment/experimental_point.py:8:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:16:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:34:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:44:1: E303 too many blank lines (3) -./src/linkage/experiment/experimental_point.py:46:66: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:47:67: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:59:47: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:60:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:86:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:89:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:18:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:38:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:48:1: E303 too many blank lines (3) +./src/linkage/experiment/experimental_point.py:50:66: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:51:67: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:63:47: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:64:1: W293 blank line contains whitespace ./src/linkage/experiment/experimental_point.py:92:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:93:24: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:93:30: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:95:75: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:99:49: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:100:42: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:108:49: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:119:38: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:120:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:141:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:95:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:96:24: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:96:30: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:98:75: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:102:49: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:103:42: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:111:49: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:123:38: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:124:1: W293 blank line contains whitespace ./src/linkage/experiment/experimental_point.py:144:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:146:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:147:24: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:147:35: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:147:41: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:151:17: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:160:41: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:160:76: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:161:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:162:35: W292 no newline at end of file +./src/linkage/experiment/experimental_point.py:150:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:153:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:154:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:155:5: E303 too many blank lines (2) +./src/linkage/experiment/experimental_point.py:155:24: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:155:35: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:155:41: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:159:17: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:168:41: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:168:76: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:169:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:170:35: W292 no newline at end of file ./src/linkage/experiment/titrator.py:6:1: E302 expected 2 blank lines, found 1 ./src/linkage/experiment/titrator.py:13:55: W291 trailing whitespace ./src/linkage/experiment/titrator.py:14:1: W293 blank line contains whitespace @@ -434,69 +525,84 @@ ./src/linkage/models/six_state_edta.py:120:35: E231 missing whitespace after ',' ./src/linkage/models/six_state_edta.py:121:1: W293 blank line contains whitespace ./src/linkage/models/six_state_edta.py:125:1: W391 blank line at end of file -./src/linkage/organizer/__init__.py:1:1: F401 'linkage.organizer.global_fit.GlobalFit' imported but unused -./src/linkage/organizer/__init__.py:1:51: W292 no newline at end of file -./src/linkage/organizer/global_fit.py:9:1: E302 expected 2 blank lines, found 1 -./src/linkage/organizer/global_fit.py:11:22: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:11:32: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:14:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:36:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:47:61: W291 trailing whitespace -./src/linkage/organizer/global_fit.py:49:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:55:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:56:59: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:58:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:59:58: W291 trailing whitespace -./src/linkage/organizer/global_fit.py:66:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:72:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:80:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:84:15: W291 trailing whitespace -./src/linkage/organizer/global_fit.py:86:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:88:53: W291 trailing whitespace -./src/linkage/organizer/global_fit.py:98:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:99:47: W291 trailing whitespace -./src/linkage/organizer/global_fit.py:114:41: W291 trailing whitespace -./src/linkage/organizer/global_fit.py:121:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:124:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:132:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:134:5: E303 too many blank lines (2) -./src/linkage/organizer/global_fit.py:136:69: W291 trailing whitespace -./src/linkage/organizer/global_fit.py:139:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:145:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:148:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:149:61: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:150:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:153:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:163:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:172:57: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:175:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:177:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:179:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:181:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:182:75: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:183:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:186:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:199:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:201:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:208:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:213:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:218:48: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:222:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:223:5: E303 too many blank lines (2) -./src/linkage/organizer/global_fit.py:223:25: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:224:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:226:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:238:78: W291 trailing whitespace -./src/linkage/organizer/global_fit.py:240:59: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:243:48: W291 trailing whitespace -./src/linkage/organizer/global_fit.py:244:53: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:247:40: E231 missing whitespace after ',' -./src/linkage/organizer/global_fit.py:253:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:259:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:271:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:275:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:276:1: W293 blank line contains whitespace -./src/linkage/organizer/global_fit.py:276:9: W292 no newline at end of file +./src/linkage/organizer/__init__.py:1:1: F401 'linkage.organizer.global_model.GlobalModel' imported but unused +./src/linkage/organizer/__init__.py:1:55: W292 no newline at end of file +./src/linkage/organizer/global_model.py:10:1: E302 expected 2 blank lines, found 1 +./src/linkage/organizer/global_model.py:12:22: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:12:32: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:15:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:37:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:48:61: W291 trailing whitespace +./src/linkage/organizer/global_model.py:50:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:56:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:57:59: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:59:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:60:58: W291 trailing whitespace +./src/linkage/organizer/global_model.py:67:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:73:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:81:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:85:15: W291 trailing whitespace +./src/linkage/organizer/global_model.py:87:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:89:53: W291 trailing whitespace +./src/linkage/organizer/global_model.py:99:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:100:47: W291 trailing whitespace +./src/linkage/organizer/global_model.py:115:41: W291 trailing whitespace +./src/linkage/organizer/global_model.py:122:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:125:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:133:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:135:5: E303 too many blank lines (2) +./src/linkage/organizer/global_model.py:137:69: W291 trailing whitespace +./src/linkage/organizer/global_model.py:140:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:146:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:149:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:150:61: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:151:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:154:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:164:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:169:49: E127 continuation line over-indented for visual indent +./src/linkage/organizer/global_model.py:170:48: E127 continuation line over-indented for visual indent +./src/linkage/organizer/global_model.py:173:57: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:176:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:178:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:180:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:182:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:183:75: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:184:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:187:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:200:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:202:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:210:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:215:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:220:48: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:224:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:225:5: E303 too many blank lines (2) +./src/linkage/organizer/global_model.py:225:19: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:226:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:229:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:241:78: W291 trailing whitespace +./src/linkage/organizer/global_model.py:243:59: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:246:56: W291 trailing whitespace +./src/linkage/organizer/global_model.py:247:53: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:250:40: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:257:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:263:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:275:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:279:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:283:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:287:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:291:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:295:25: E231 missing whitespace after ':' +./src/linkage/organizer/global_model.py:296:27: E231 missing whitespace after ':' +./src/linkage/organizer/global_model.py:297:26: E231 missing whitespace after ':' +./src/linkage/organizer/global_model.py:306:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:309:34: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:315:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:316:36: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:326:52: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:329:52: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:330:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:337:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:337:9: W292 no newline at end of file ./tests/conftest.py:11:1: E302 expected 2 blank lines, found 1 ./tests/conftest.py:42:63: E231 missing whitespace after ',' ./tests/conftest.py:56:49: E231 missing whitespace after ',' @@ -562,24 +668,68 @@ ./tests/linkage/experiment/test_titrator.py:16:1: W293 blank line contains whitespace ./tests/linkage/experiment/test_titrator.py:19:31: E231 missing whitespace after ',' ./tests/linkage/experiment/test_titrator.py:21:1: W391 blank line at end of file -./tests/linkage/organizer/test_global_fit.py:3:1: F401 'pytest' imported but unused -./tests/linkage/organizer/test_global_fit.py:5:1: F401 'linkage' imported but unused -./tests/linkage/organizer/test_global_fit.py:8:1: F401 'numpy as np' imported but unused -./tests/linkage/organizer/test_global_fit.py:11:1: E302 expected 2 blank lines, found 1 -./tests/linkage/organizer/test_global_fit.py:16:5: E303 too many blank lines (2) -./tests/linkage/organizer/test_global_fit.py:20:1: W293 blank line contains whitespace -1 E127 continuation line over-indented for visual indent -6 E128 continuation line under-indented for visual indent +./tests/linkage/organizer/test_global_model.py:14:1: E302 expected 2 blank lines, found 1 +./tests/linkage/organizer/test_global_model.py:21:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:25:31: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:35:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:37:35: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:39:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:40:5: E303 too many blank lines (2) +./tests/linkage/organizer/test_global_model.py:43:51: W291 trailing whitespace +./tests/linkage/organizer/test_global_model.py:46:5: E303 too many blank lines (2) +./tests/linkage/organizer/test_global_model.py:50:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:54:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:58:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:59:1: E302 expected 2 blank lines, found 1 +./tests/linkage/organizer/test_global_model.py:66:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:69:39: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:69:48: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:69:53: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:70:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:73:39: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:73:48: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:73:53: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:73:58: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:74:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:77:46: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:79:1: E302 expected 2 blank lines, found 1 +./tests/linkage/organizer/test_global_model.py:91:46: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:100:46: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:102:1: E302 expected 2 blank lines, found 1 +./tests/linkage/organizer/test_global_model.py:112:23: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:112:30: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:112:37: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:113:25: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:113:34: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:113:43: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:113:52: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:116:35: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:126:1: E302 expected 2 blank lines, found 1 +./tests/linkage/organizer/test_global_model.py:139:1: E302 expected 2 blank lines, found 1 +./tests/linkage/organizer/test_global_model.py:141:59: W291 trailing whitespace +./tests/linkage/organizer/test_global_model.py:143:51: W291 trailing whitespace +./tests/linkage/organizer/test_global_model.py:146:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:161:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:162:5: E303 too many blank lines (2) +./tests/linkage/organizer/test_global_model.py:162:39: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:163:38: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:165:46: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:165:56: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:173:5: E303 too many blank lines (2) +./tests/linkage/organizer/test_global_model.py:177:22: E128 continuation line under-indented for visual indent +./tests/linkage/organizer/test_global_model.py:177:47: W292 no newline at end of file +5 E127 continuation line over-indented for visual indent +7 E128 continuation line under-indented for visual indent 6 E225 missing whitespace around operator -242 E231 missing whitespace after ',' -20 E302 expected 2 blank lines, found 1 -8 E303 too many blank lines (3) +298 E231 missing whitespace after ',' +26 E302 expected 2 blank lines, found 1 +15 E303 too many blank lines (3) 2 E741 ambiguous variable name 'I' -15 F401 'linkage.experiment.Experiment' imported but unused +12 F401 'linkage.experiment.Experiment' imported but unused 1 F541 f-string is missing placeholders 2 F841 local variable 'args' is assigned to but never used -66 W291 trailing whitespace -12 W292 no newline at end of file -186 W293 blank line contains whitespace +78 W291 trailing whitespace +14 W292 no newline at end of file +251 W293 blank line contains whitespace 3 W391 blank line at end of file -570 +720 diff --git a/reports/junit/junit.xml b/reports/junit/junit.xml index b807fc5..5a8bdf1 100644 --- a/reports/junit/junit.xml +++ b/reports/junit/junit.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/linkage/__init__.py b/src/linkage/__init__.py index 2ab7b9a..8d73d49 100644 --- a/src/linkage/__init__.py +++ b/src/linkage/__init__.py @@ -1,6 +1,6 @@ import linkage from linkage.experiment import Experiment -from linkage.organizer import GlobalFit +from linkage.organizer import GlobalModel # Make a list of all classes in linkage.models diff --git a/src/linkage/experiment/experimental_point.py b/src/linkage/experiment/experimental_point.py index 9382260..0de41f8 100644 --- a/src/linkage/experiment/experimental_point.py +++ b/src/linkage/experiment/experimental_point.py @@ -9,7 +9,9 @@ class ExperimentalPoint: def __init__(self, idx, expt_idx, - obs_key): + obs_key, + micro_array, + macro_array): """ Should be sub-classed. """ @@ -17,6 +19,8 @@ def __init__(self, self._idx = idx self._expt_idx = expt_idx self._obs_key = obs_key + self._micro_array = micro_array + self._macro_array = macro_array @property def idx(self): @@ -51,10 +55,10 @@ def __init__(self, idx, expt_idx, obs_key, - obs_mask, - denom, micro_array, - macro_array): + macro_array, + obs_mask, + denom,): """ Initialize a spectroscopic data point. @@ -66,30 +70,29 @@ def __init__(self, index of the experiment itself (allowing multiple experiments) obs_key : str key pointing to observable from the experiment - obs_mask : np.ndarray (bool or int) - mask that grabs microscopic species from micro_array that correspond - to the numerator when calculating the observable - denom : int - index of the macro species that should be used as the denominator - for the observable calculation micro_array : np.ndarray (float) array holding concentrations of all microscopic species, calculated elsewhere macro_array : np.ndarray (float) array holding concentrations of all macroscopic species, calculated elsewhere + obs_mask : np.ndarray (bool or int) + mask that grabs microscopic species from micro_array that correspond + to the numerator when calculating the observable + denom : int + index of the macro species that should be used as the denominator + for the observable calculation """ super().__init__(idx=idx, expt_idx=expt_idx, - obs_key=obs_key) + obs_key=obs_key, + micro_array=micro_array, + macro_array=macro_array) self._obs_mask = obs_mask self._denom = denom - self._micro_array = micro_array - self._macro_array = macro_array - def calc_value(self,*args,**kwargs): """ Calculate the observable given the estimated concentrations of all @@ -112,9 +115,10 @@ def __init__(self, idx, expt_idx, obs_key, + micro_array, + macro_array, dh_param_start_idx, - dh_param_end_idx, - micro_array): + dh_param_end_idx): """ Initialize an ITC data point. @@ -126,23 +130,27 @@ def __init__(self, index of the experiment itself (allowing multiple experiments) obs_key : str key pointing to observable from the experiment + micro_array : np.ndarray (float) + array holding concentrations of all microscopic species, calculated + elsewhere + macro_array : np.ndarray (float) + array holding concentrations of all macroscopic species, calculated + elsewhere dh_param_start_idx : int index of first enthalpy parameter in guesses array dh_param_end_idx : int index of last enthalpy parameter in guesses array - micro_array : np.ndarray (float) - array holding concentrations of all microscopic species, calculated - elsewhere """ - + super().__init__(idx=idx, expt_idx=expt_idx, - obs_key=obs_key) + obs_key=obs_key, + micro_array=micro_array, + macro_array=macro_array) self._dh_param_start_idx = dh_param_start_idx self._dh_param_end_idx = dh_param_end_idx - self._micro_array = micro_array def calc_value(self,parameters,*args,**kwargs): """ diff --git a/src/linkage/organizer/__init__.py b/src/linkage/organizer/__init__.py index 01e9ea3..691a4b0 100644 --- a/src/linkage/organizer/__init__.py +++ b/src/linkage/organizer/__init__.py @@ -1 +1 @@ -from linkage.organizer.global_fit import GlobalFit \ No newline at end of file +from linkage.organizer.global_model import GlobalModel \ No newline at end of file diff --git a/src/linkage/organizer/global_fit.py b/src/linkage/organizer/global_model.py similarity index 81% rename from src/linkage/organizer/global_fit.py rename to src/linkage/organizer/global_model.py index 8271bc8..dc7bd79 100644 --- a/src/linkage/organizer/global_fit.py +++ b/src/linkage/organizer/global_model.py @@ -3,10 +3,11 @@ from linkage.experiment.experimental_point import ITCPoint import numpy as np +import pandas as pd import copy -class GlobalFit: +class GlobalModel: def __init__(self,expt_list,model_name="SixStateEDTA"): """ @@ -17,7 +18,7 @@ def __init__(self,expt_list,model_name="SixStateEDTA"): expt_list : list list of experiments with loaded observations model_name : str - name of model to use for the analysis + name of model to use to calculate concentrations """ # Store model name and experiment list @@ -164,9 +165,9 @@ def _build_point_map(self): for expt_counter, expt in enumerate(self._expt_list): # Each experiment will have a an array of microscopic species concentrations - self._micro_arrays.append(np.zeros((len(expt.expt_data), + self._micro_arrays.append(np.ones((len(expt.expt_data), len(self._bm.micro_species)), - dtype=float)) + dtype=float)*np.nan) # ... and an array of macroscopic species concentrations macro_array = np.array(expt.expt_concs.loc[:,self._bm.macro_species], @@ -191,20 +192,21 @@ def _build_point_map(self): pt = SpecPoint(idx=i, expt_idx=expt_counter, obs_key=obs, + micro_array=self._micro_arrays[-1], + macro_array=self._macro_arrays[-1], obs_mask=np.isin(self._bm.micro_species, obs_info["observable_species"]), - denom=den_index, - micro_array=self._micro_arrays[-1], - macro_array=self._macro_arrays[-1]) + denom=den_index) elif obs_info["obs_type"] == "itc": pt = ITCPoint(idx=i, expt_idx=expt_counter, obs_key=obs, + micro_array=self._micro_arrays[-1], + macro_array=self._macro_arrays[-1], dh_param_start_idx=self._dh_param_start_idx, - dh_param_end_idx=self._dh_param_end_idx + 1, - micro_array=self._micro_arrays[-1]) + dh_param_end_idx=self._dh_param_end_idx + 1) else: obs_type = obs_info["obs_type"] @@ -220,8 +222,9 @@ def _build_point_map(self): self._y_stdev = np.array(self._y_stdev)/np.sum(self._y_stdev) - def total_model(self,guesses): + def model(self,guesses): + # For each block of macro species for i in range(len(self._macro_arrays)): # Figure out if we are fudging a macro array species concentration @@ -240,14 +243,15 @@ def total_model(self,guesses): this_macro_array = self._macro_arrays[i][j,:] this_macro_array[fudge_species_index] *= fudge_value - # Grab parameters from guesses. + # Grab binding parameters from guesses. this_param_array = np.float_power(10,guesses[self._bm_param_start_idx:self._bm_param_end_idx+1]) # Update microscopic species concentrations self._micro_arrays[i][j,:] = self._bm.get_concs(param_array=this_param_array, macro_array=this_macro_array) - # For each point, calculate the observable + # For each point, calculate the observable given the estimated microscopic + # and macroscopic concentrations for i in range(len(self._points)): self._y_calc[i] = self._points[i].calc_value(guesses) @@ -273,4 +277,61 @@ def parameter_names(self): def parameter_guesses(self): return self._parameter_guesses + @property + def model_name(self): + return self._model_name + + @property + def macro_species(self): + return self._bm.macro_species + + @property + def micro_species(self): + return self._micro_species + + @property + def as_df(self): + + out = {"expt_id":[], + "expt_type":[], + "expt_obs":[]} + + for k in self._bm.macro_species: + out[k] = [] + + for k in self._bm.micro_species: + out[k] = [] + + for p in self._points: + + out["expt_id"].append(p.expt_idx) + + if issubclass(type(p),SpecPoint): + out["expt_type"].append(p.obs_key) + + num = "+".join(self._bm.micro_species[p._obs_mask]) + den = self._bm.macro_species[p._denom] + out["expt_obs"].append(f"{num}/{den}") + + elif issubclass(type(p),ITCPoint): + out["expt_type"].append("itc") + + out["expt_obs"].append("heat") + + else: + err = "point class not recognized\n" + raise ValueError(err) + + for i, k in enumerate(self._bm.macro_species): + out[k].append(p._macro_array[p._idx,i]) + + for i, k in enumerate(self._bm.micro_species): + out[k].append(p._micro_array[p._idx,i]) + + out["y_obs"] = self.y_obs + out["y_calc"] = self.y_calc + out["y_stdev"] = self.y_stdev + + return pd.DataFrame(out) + \ No newline at end of file diff --git a/tests/linkage/organizer/test_global_fit.py b/tests/linkage/organizer/test_global_fit.py deleted file mode 100644 index c77ff17..0000000 --- a/tests/linkage/organizer/test_global_fit.py +++ /dev/null @@ -1,21 +0,0 @@ - - -import pytest - -import linkage -from linkage.organizer.global_fit import GlobalFit - -import numpy as np -import copy - -def test_GlobalFit_integrated(fake_spec_and_itc_data): - - base_expt_list = copy.deepcopy(fake_spec_and_itc_data) - - - this_expt_list = copy.deepcopy(base_expt_list) - - gf = GlobalFit(model_name="SixStateEDTA", - expt_list=this_expt_list) - - gf.total_model(gf.parameter_guesses) diff --git a/tests/linkage/organizer/test_global_model.py b/tests/linkage/organizer/test_global_model.py new file mode 100644 index 0000000..3c5bb2d --- /dev/null +++ b/tests/linkage/organizer/test_global_model.py @@ -0,0 +1,177 @@ + + +import pytest + +import linkage +from linkage.organizer.global_model import GlobalModel +from linkage.experiment.experimental_point import SpecPoint +from linkage.experiment.experimental_point import ITCPoint + +import numpy as np +import pandas as pd +import copy + +def test_GlobalModel_integrated(fake_spec_and_itc_data): + + base_expt_list = copy.deepcopy(fake_spec_and_itc_data) + this_expt_list = copy.deepcopy(base_expt_list) + + gf = GlobalModel(model_name="SixStateEDTA", + expt_list=this_expt_list) + + gf.model(gf.parameter_guesses) + + df = gf.as_df + assert issubclass(type(df),pd.DataFrame) + + +def test_GlobalModel__load_model(fake_spec_and_itc_data): + + base_expt_list = copy.deepcopy(fake_spec_and_itc_data) + this_expt_list = copy.deepcopy(base_expt_list) + + gf = GlobalModel(model_name="SixStateEDTA", + expt_list=this_expt_list) + + assert gf._model_name == "SixStateEDTA" + assert issubclass(type(gf._bm),linkage.models.six_state_edta.SixStateEDTA) + + + this_expt_list = copy.deepcopy(base_expt_list) + with pytest.raises(ValueError): + gf = GlobalModel(model_name="not_a_model", + expt_list=this_expt_list) + + + this_expt_list = copy.deepcopy(base_expt_list) + + gf = GlobalModel(model_name="SixStateEDTA", + expt_list=this_expt_list) + + assert gf._model_name == "SixStateEDTA" + assert issubclass(type(gf._bm), + linkage.models.six_state_edta.SixStateEDTA) + + param_names = linkage.models.six_state_edta.SixStateEDTA().param_names + assert np.array_equal(param_names, + gf.parameter_names[:len(param_names)]) + +def test_GlobalModel__sync_model_and_expt(fake_spec_and_itc_data): + + base_expt_list = copy.deepcopy(fake_spec_and_itc_data) + this_expt_list = copy.deepcopy(base_expt_list) + + gf = GlobalModel(model_name="SixStateEDTA", + expt_list=this_expt_list) + + # Make sure array starts without AT + assert np.array_equal(this_expt_list[1].expt_concs.columns, + ["injection","volume","CT","ET"]) + + # make sure we added AT + assert np.array_equal(gf._expt_list[1].expt_concs.columns, + ["injection","volume","CT","ET","AT"]) + + num_points = len(gf._expt_list[1].expt_concs["AT"]) + assert np.array_equal(gf._expt_list[1].expt_concs["AT"], + np.zeros(num_points,dtype=float)) + +def test_GlobalModel__count_expt_points(fake_spec_and_itc_data): + + base_expt_list = copy.deepcopy(fake_spec_and_itc_data) + this_expt_list = copy.deepcopy(base_expt_list) + + counts = [] + for expt in this_expt_list: + counts.append(np.sum(np.logical_not(np.array(expt.expt_data["ignore_point"])))) + counts[-1] = counts[-1]*len(expt.observables) + + gf = GlobalModel(model_name="SixStateEDTA", + expt_list=this_expt_list) + assert np.array_equal(gf._points_per_expt,counts) + + # Set whole experiment to ignore_point is True, turning experiment off + this_expt_list = copy.deepcopy(base_expt_list) + this_expt_list[0].expt_data["ignore_point"] = True + counts[0] = 0 + + gf = GlobalModel(model_name="SixStateEDTA", + expt_list=this_expt_list) + assert np.array_equal(gf._points_per_expt,counts) + +def test_GlobalModel__get_enthalpy_param(fake_spec_and_itc_data): + + base_expt_list = copy.deepcopy(fake_spec_and_itc_data) + + this_expt_list = copy.deepcopy(base_expt_list) + gf = GlobalModel(model_name="SixStateEDTA", + expt_list=this_expt_list) + assert gf._dh_param_start_idx is not None + assert gf._dh_param_end_idx is not None + + expected = ['dH_I','dH_A','dH_C','dH_E', + 'dH_AC1','dH_AC2','dH_AC3','dH_AC4','dH_EC'] + dh_param = gf._all_parameter_names[gf._dh_param_start_idx:gf._dh_param_end_idx + 1] + + assert np.array_equal(expected,dh_param) + + # Remove itc experiment; should have no enthalpies + this_expt_list = copy.deepcopy(base_expt_list) + this_expt_list.pop(-1) + gf = GlobalModel(model_name="SixStateEDTA", + expt_list=this_expt_list) + assert gf._dh_param_start_idx is None + assert gf._dh_param_end_idx is None + +def test_GlobalModel__process_expt_fudge(fake_spec_and_itc_data): + + base_expt_list = copy.deepcopy(fake_spec_and_itc_data) + + this_expt_list = copy.deepcopy(base_expt_list) + gf = GlobalModel(model_name="SixStateEDTA", + expt_list=this_expt_list) + assert gf.parameter_names[-1] == "expt_0_AT_fudge" + assert gf.parameter_guesses[-1] == 1.0 + assert gf._fudge_list[0][0] == 0 + assert gf._fudge_list[0][1] == len(gf.parameter_names) - 1 + assert gf._fudge_list[1] is None + +def test_GlobalModel__build_point_map(fake_spec_and_itc_data): + + base_expt_list = copy.deepcopy(fake_spec_and_itc_data) + + this_expt_list = copy.deepcopy(base_expt_list) + gf = GlobalModel(model_name="SixStateEDTA", + expt_list=this_expt_list) + + assert len(gf._micro_arrays) == 2 + assert gf._micro_arrays[0].shape[1] == len(gf._bm.micro_species) + assert gf._micro_arrays[1].shape[1] == len(gf._bm.micro_species) + + assert len(gf._macro_arrays) == 2 + assert gf._macro_arrays[0].shape[1] == len(gf._bm.macro_species) + assert gf._macro_arrays[1].shape[1] == len(gf._bm.macro_species) + + num_points = 0 + for expt in this_expt_list: + num_obs = len(expt.observables) + num_not_ignore = np.sum(np.logical_not(expt._expt_data["ignore_point"])) + num_points += num_obs*num_not_ignore + + + num_spec = sum([issubclass(type(p),SpecPoint) for p in gf._points]) + num_itc = sum([issubclass(type(p),ITCPoint) for p in gf._points]) + + assert np.array_equal(gf._points_per_expt,[num_spec,num_itc]) + + assert num_points == len(gf._points) + assert num_points == len(gf._y_obs) + assert num_points == len(gf._y_stdev) + assert num_points == len(gf._y_calc) + + + this_expt_list = copy.deepcopy(base_expt_list) + this_expt_list[0].observables["cd222"]["obs_type"] = "not_really" + with pytest.raises(ValueError): + gf = GlobalModel(model_name="SixStateEDTA", + expt_list=this_expt_list) \ No newline at end of file From 1010ee609311258e5867f6ac0535299fab7c339e Mon Sep 17 00:00:00 2001 From: Michael Harms Date: Wed, 24 Jul 2024 17:49:20 -0700 Subject: [PATCH 04/17] added single-site binding model --- .github/workflows/python-app.yml | 4 +- docs/badges/coverage-badge.svg | 2 +- docs/badges/tests-badge.svg | 2 +- reports/flake.txt | 114 ++++++++++++++++++++++++--- reports/junit/junit.xml | 2 +- src/linkage/models/__init__.py | 1 + src/linkage/models/ca_edta.py | 66 ++++++++++++++++ tests/linkage/models/test_ca_edta.py | 64 +++++++++++++++ 8 files changed, 239 insertions(+), 16 deletions(-) create mode 100644 src/linkage/models/ca_edta.py create mode 100644 tests/linkage/models/test_ca_edta.py diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 034ad54..fe51da9 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -1,7 +1,5 @@ -# This workflow will install Python dependencies, run tests and lint with a single version of Python -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions -name: dataprob +name: linkage on: push: diff --git a/docs/badges/coverage-badge.svg b/docs/badges/coverage-badge.svg index 34601e6..41d0820 100644 --- a/docs/badges/coverage-badge.svg +++ b/docs/badges/coverage-badge.svg @@ -1 +1 @@ -coverage: 77.01%coverage77.01% \ No newline at end of file +coverage: 80.89%coverage80.89% \ No newline at end of file diff --git a/docs/badges/tests-badge.svg b/docs/badges/tests-badge.svg index fe9b4a3..86669c1 100644 --- a/docs/badges/tests-badge.svg +++ b/docs/badges/tests-badge.svg @@ -1 +1 @@ -tests: 8tests8 \ No newline at end of file +tests: 9tests9 \ No newline at end of file diff --git a/reports/flake.txt b/reports/flake.txt index 26af4c3..3fbc75e 100644 --- a/reports/flake.txt +++ b/reports/flake.txt @@ -108,6 +108,7 @@ ./build/lib/linkage/experiment/titrator.py:93:1: W293 blank line contains whitespace ./build/lib/linkage/experiment/titrator.py:102:1: W293 blank line contains whitespace ./build/lib/linkage/models/__init__.py:2:1: F401 'linkage.models.six_state_edta.SixStateEDTA' imported but unused +./build/lib/linkage/models/__init__.py:3:1: F401 'linkage.models.ca_edta.CaEDTA' imported but unused ./build/lib/linkage/models/base.py:4:1: E302 expected 2 blank lines, found 1 ./build/lib/linkage/models/base.py:8:1: W293 blank line contains whitespace ./build/lib/linkage/models/base.py:9:23: E231 missing whitespace after ',' @@ -122,6 +123,31 @@ ./build/lib/linkage/models/base.py:18:35: E231 missing whitespace after ',' ./build/lib/linkage/models/base.py:19:1: W293 blank line contains whitespace ./build/lib/linkage/models/base.py:22:80: W292 no newline at end of file +./build/lib/linkage/models/ca_edta.py:8:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/models/ca_edta.py:10:1: W293 blank line contains whitespace +./build/lib/linkage/models/ca_edta.py:11:5: E303 too many blank lines (2) +./build/lib/linkage/models/ca_edta.py:11:23: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:11:35: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:17:32: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:17:35: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:17:40: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:28:44: E225 missing whitespace around operator +./build/lib/linkage/models/ca_edta.py:29:44: E225 missing whitespace around operator +./build/lib/linkage/models/ca_edta.py:30:44: E225 missing whitespace around operator +./build/lib/linkage/models/ca_edta.py:32:1: W293 blank line contains whitespace +./build/lib/linkage/models/ca_edta.py:36:36: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:37:1: W293 blank line contains whitespace +./build/lib/linkage/models/ca_edta.py:40:1: W293 blank line contains whitespace +./build/lib/linkage/models/ca_edta.py:41:73: W291 trailing whitespace +./build/lib/linkage/models/ca_edta.py:42:75: W291 trailing whitespace +./build/lib/linkage/models/ca_edta.py:44:48: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:47:40: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:54:27: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:54:29: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:54:33: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:62:30: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:63:1: W293 blank line contains whitespace +./build/lib/linkage/models/ca_edta.py:66:42: W292 no newline at end of file ./build/lib/linkage/models/six_state_edta.py:10:1: E302 expected 2 blank lines, found 1 ./build/lib/linkage/models/six_state_edta.py:17:1: W293 blank line contains whitespace ./build/lib/linkage/models/six_state_edta.py:18:25: E231 missing whitespace after ',' @@ -444,6 +470,7 @@ ./src/linkage/experiment/titrator.py:93:1: W293 blank line contains whitespace ./src/linkage/experiment/titrator.py:102:1: W293 blank line contains whitespace ./src/linkage/models/__init__.py:2:1: F401 'linkage.models.six_state_edta.SixStateEDTA' imported but unused +./src/linkage/models/__init__.py:3:1: F401 'linkage.models.ca_edta.CaEDTA' imported but unused ./src/linkage/models/base.py:4:1: E302 expected 2 blank lines, found 1 ./src/linkage/models/base.py:8:1: W293 blank line contains whitespace ./src/linkage/models/base.py:9:23: E231 missing whitespace after ',' @@ -458,6 +485,32 @@ ./src/linkage/models/base.py:18:35: E231 missing whitespace after ',' ./src/linkage/models/base.py:19:1: W293 blank line contains whitespace ./src/linkage/models/base.py:22:80: W292 no newline at end of file +./src/linkage/models/ca_edta.py:8:1: E302 expected 2 blank lines, found 1 +./src/linkage/models/ca_edta.py:10:1: W293 blank line contains whitespace +./src/linkage/models/ca_edta.py:11:5: E303 too many blank lines (2) +./src/linkage/models/ca_edta.py:11:23: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:11:35: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:17:32: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:17:35: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:17:40: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:28:44: E225 missing whitespace around operator +./src/linkage/models/ca_edta.py:29:44: E225 missing whitespace around operator +./src/linkage/models/ca_edta.py:30:44: E225 missing whitespace around operator +./src/linkage/models/ca_edta.py:32:1: W293 blank line contains whitespace +./src/linkage/models/ca_edta.py:36:36: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:37:1: W293 blank line contains whitespace +./src/linkage/models/ca_edta.py:38:58: W291 trailing whitespace +./src/linkage/models/ca_edta.py:40:1: W293 blank line contains whitespace +./src/linkage/models/ca_edta.py:41:73: W291 trailing whitespace +./src/linkage/models/ca_edta.py:42:75: W291 trailing whitespace +./src/linkage/models/ca_edta.py:44:48: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:47:40: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:54:27: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:54:29: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:54:33: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:62:30: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:63:1: W293 blank line contains whitespace +./src/linkage/models/ca_edta.py:66:42: W292 no newline at end of file ./src/linkage/models/six_state_edta.py:10:1: E302 expected 2 blank lines, found 1 ./src/linkage/models/six_state_edta.py:17:1: W293 blank line contains whitespace ./src/linkage/models/six_state_edta.py:18:25: E231 missing whitespace after ',' @@ -668,6 +721,47 @@ ./tests/linkage/experiment/test_titrator.py:16:1: W293 blank line contains whitespace ./tests/linkage/experiment/test_titrator.py:19:31: E231 missing whitespace after ',' ./tests/linkage/experiment/test_titrator.py:21:1: W391 blank line at end of file +./tests/linkage/models/test_ca_edta.py:7:1: E302 expected 2 blank lines, found 1 +./tests/linkage/models/test_ca_edta.py:9:27: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:9:39: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:9:51: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:14:49: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:15:43: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:18:5: E303 too many blank lines (2) +./tests/linkage/models/test_ca_edta.py:20:43: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:20:58: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:21:43: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:21:57: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:21:61: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:26:47: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:30:5: E303 too many blank lines (2) +./tests/linkage/models/test_ca_edta.py:33:47: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:38:49: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:39:29: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:39:41: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:39:47: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:42:52: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:43:29: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:43:44: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:43:46: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:46:49: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:47:29: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:47:41: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:47:43: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:53:56: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:54:36: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:54:53: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:54:66: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:58:58: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:59:36: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:59:53: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:59:66: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:63:29: E128 continuation line under-indented for visual indent +./tests/linkage/models/test_ca_edta.py:63:57: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:64:36: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:64:53: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:64:66: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:64:82: W292 no newline at end of file ./tests/linkage/organizer/test_global_model.py:14:1: E302 expected 2 blank lines, found 1 ./tests/linkage/organizer/test_global_model.py:21:1: W293 blank line contains whitespace ./tests/linkage/organizer/test_global_model.py:25:31: E231 missing whitespace after ',' @@ -719,17 +813,17 @@ ./tests/linkage/organizer/test_global_model.py:177:22: E128 continuation line under-indented for visual indent ./tests/linkage/organizer/test_global_model.py:177:47: W292 no newline at end of file 5 E127 continuation line over-indented for visual indent -7 E128 continuation line under-indented for visual indent -6 E225 missing whitespace around operator -298 E231 missing whitespace after ',' -26 E302 expected 2 blank lines, found 1 -15 E303 too many blank lines (3) +8 E128 continuation line under-indented for visual indent +12 E225 missing whitespace around operator +358 E231 missing whitespace after ',' +29 E302 expected 2 blank lines, found 1 +19 E303 too many blank lines (3) 2 E741 ambiguous variable name 'I' -12 F401 'linkage.experiment.Experiment' imported but unused +14 F401 'linkage.experiment.Experiment' imported but unused 1 F541 f-string is missing placeholders 2 F841 local variable 'args' is assigned to but never used -78 W291 trailing whitespace -14 W292 no newline at end of file -251 W293 blank line contains whitespace +83 W291 trailing whitespace +17 W292 no newline at end of file +261 W293 blank line contains whitespace 3 W391 blank line at end of file -720 +814 diff --git a/reports/junit/junit.xml b/reports/junit/junit.xml index 5a8bdf1..fd24fa6 100644 --- a/reports/junit/junit.xml +++ b/reports/junit/junit.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/linkage/models/__init__.py b/src/linkage/models/__init__.py index 90923c5..9e812f0 100644 --- a/src/linkage/models/__init__.py +++ b/src/linkage/models/__init__.py @@ -1,2 +1,3 @@ from linkage.models.six_state_edta import SixStateEDTA +from linkage.models.ca_edta import CaEDTA diff --git a/src/linkage/models/ca_edta.py b/src/linkage/models/ca_edta.py new file mode 100644 index 0000000..2b8d887 --- /dev/null +++ b/src/linkage/models/ca_edta.py @@ -0,0 +1,66 @@ + +from linkage.models.base import BindingModel + +import numpy as np + +import warnings + +class CaEDTA(BindingModel): + + + def get_concs(self,param_array,macro_array): + + KE = param_array[0] + CT, ET = macro_array + + if CT == 0 or ET == 0: + return np.array([CT,ET,0.0],dtype=float) + + # Simple quadratic + # a = 1 + b = -(CT + ET + 1/KE) + c = ET*CT + s = np.sqrt(b**2 - 4*c) + roots = np.array([(-b + s)/2, (-b - s)/2]) + + # Get real root that has concentration <= CT and <= ET + mask = np.logical_and.reduce((np.isreal(roots), + roots>=0, + roots<=CT, + roots<=ET)) + solution = np.unique(roots[mask]) + + # No real root between 0 and CT. Return np.nan for all concentrations + if len(solution) == 0: + warnings.warn("no roots found\n") + return np.nan*np.ones(3,dtype=float) + + # Multiple real roots between 0 and CT, 0 and ET. + if len(solution) > 1: + + # Check whether the all roots are numerically close and thus + # arise from float imprecision. If really have multiple roots, + # return np.nan for all concentrations + close_mask = np.isclose(solution[0],solution) + if np.sum(close_mask) != len(solution): + warnings.warn("multiple roots found\n") + return np.nan*np.ones(3,dtype=float) + + # Get species + EC = np.real(solution[0]) + C = CT - EC + E = ET - EC + + return np.array([C,E,EC],dtype=float) + + @property + def param_names(self): + return np.array(["KE"]) + + @property + def macro_species(self): + return np.array(["CT","ET"]) + + @property + def micro_species(self): + return np.array(["C", "E", "EC"]) \ No newline at end of file diff --git a/tests/linkage/models/test_ca_edta.py b/tests/linkage/models/test_ca_edta.py new file mode 100644 index 0000000..30e9028 --- /dev/null +++ b/tests/linkage/models/test_ca_edta.py @@ -0,0 +1,64 @@ +import pytest + +from linkage.models.ca_edta import CaEDTA + +import numpy as np + +def test_CaEDTA_integrated(): + + def _check_with_log(bm,param_array,macro_array,expected_values): + + concs = bm.get_concs(param_array=param_array, + macro_array=macro_array) + + log_round_concs = np.round(np.log(concs),3) + assert np.allclose(log_round_concs,expected_values) + + + bm = CaEDTA() + + assert np.array_equal(bm.macro_species,np.array(["CT","ET"])) + assert np.array_equal(bm.micro_species,np.array(["C","E","EC"])) + + print("basic check") + _check_with_log(bm=bm, + param_array=np.array([1e7]), + macro_array=np.array([1e-7,1e-10]), + expected_values=np.array([-16.119, -23.719, -23.719])) + + + print("another arbitrary conc check") + _check_with_log(bm=bm, + param_array=np.array([1e7]), + macro_array=np.array([1e-3,1e-3]), + expected_values=np.array([-11.518, -11.518, -6.918])) + + print("zero checks") + concs = bm.get_concs(param_array=np.array([1e7]), + macro_array=np.array([0,1e-10])) + assert np.allclose(concs,np.array([0,1e-10,0])) + + concs = bm.get_concs(param_array=np.array([1e7]), + macro_array=np.array([1e-7,0])) + assert np.allclose(concs,np.array([1e-7,0,0])) + + concs = bm.get_concs(param_array=np.array([1e7]), + macro_array=np.array([0,0])) + assert np.allclose(concs,np.array([0,0,0])) + + print("graceful na checks") + + with pytest.warns(): + concs = bm.get_concs(param_array=np.array([np.nan]), + macro_array=np.array([1e-7,1e-10])) + assert np.array_equal(concs,np.nan*np.ones(3,dtype=float),equal_nan=True) + + with pytest.warns(): + concs = bm.get_concs(param_array=np.array([1e7]), + macro_array=np.array([np.nan,1e-10])) + assert np.array_equal(concs,np.nan*np.ones(3,dtype=float),equal_nan=True) + + with pytest.warns(): + concs = bm.get_concs(param_array=np.array([np.nan]), + macro_array=np.array([np.nan,np.nan])) + assert np.array_equal(concs,np.nan*np.ones(3,dtype=float),equal_nan=True) \ No newline at end of file From 9050b860ebe338d88656922125f3e6d86720836d Mon Sep 17 00:00:00 2001 From: Michael Harms Date: Thu, 25 Jul 2024 15:01:14 -0700 Subject: [PATCH 05/17] model definitions now include awareness of reactions --- docs/badges/coverage-badge.svg | 2 +- docs/badges/tests-badge.svg | 2 +- reports/flake.txt | 1248 ++++++++++++------ reports/junit/junit.xml | 2 +- src/linkage/experiment/experiment.py | 2 +- src/linkage/experiment/experimental_point.py | 8 +- src/linkage/experiment/titrator.py | 7 + src/linkage/models/base.py | 369 +++++- src/linkage/models/ca_edta.py | 18 +- src/linkage/models/six_state_edta.py | 28 +- src/linkage/organizer/global_model.py | 37 +- tests/linkage/models/test_base.py | 513 +++++++ tests/linkage/organizer/test_global_model.py | 4 +- 13 files changed, 1841 insertions(+), 399 deletions(-) create mode 100644 tests/linkage/models/test_base.py diff --git a/docs/badges/coverage-badge.svg b/docs/badges/coverage-badge.svg index 41d0820..4ed2f95 100644 --- a/docs/badges/coverage-badge.svg +++ b/docs/badges/coverage-badge.svg @@ -1 +1 @@ -coverage: 80.89%coverage80.89% \ No newline at end of file +coverage: 91.73%coverage91.73% \ No newline at end of file diff --git a/docs/badges/tests-badge.svg b/docs/badges/tests-badge.svg index 86669c1..94169cd 100644 --- a/docs/badges/tests-badge.svg +++ b/docs/badges/tests-badge.svg @@ -1 +1 @@ -tests: 9tests9 \ No newline at end of file +tests: 15tests15 \ No newline at end of file diff --git a/reports/flake.txt b/reports/flake.txt index 3fbc75e..124a480 100644 --- a/reports/flake.txt +++ b/reports/flake.txt @@ -74,21 +74,23 @@ ./build/lib/linkage/experiment/experimental_point.py:102:49: E231 missing whitespace after ',' ./build/lib/linkage/experiment/experimental_point.py:103:42: E231 missing whitespace after ',' ./build/lib/linkage/experiment/experimental_point.py:111:49: W291 trailing whitespace -./build/lib/linkage/experiment/experimental_point.py:123:38: W291 trailing whitespace -./build/lib/linkage/experiment/experimental_point.py:124:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:144:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:150:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:153:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:154:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:155:5: E303 too many blank lines (2) -./build/lib/linkage/experiment/experimental_point.py:155:24: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:155:35: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:155:41: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:159:17: W291 trailing whitespace -./build/lib/linkage/experiment/experimental_point.py:168:41: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:168:76: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experimental_point.py:169:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experimental_point.py:170:35: W292 no newline at end of file +./build/lib/linkage/experiment/experimental_point.py:124:38: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:125:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:142:75: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:149:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:155:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:159:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:160:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:161:5: E303 too many blank lines (2) +./build/lib/linkage/experiment/experimental_point.py:161:24: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:161:35: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:161:41: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:165:17: W291 trailing whitespace +./build/lib/linkage/experiment/experimental_point.py:174:41: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:174:76: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experimental_point.py:175:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experimental_point.py:176:35: W292 no newline at end of file +./build/lib/linkage/experiment/titrator.py:6:1: C901 'titrator' is too complex (11) ./build/lib/linkage/experiment/titrator.py:6:1: E302 expected 2 blank lines, found 1 ./build/lib/linkage/experiment/titrator.py:13:55: W291 trailing whitespace ./build/lib/linkage/experiment/titrator.py:14:1: W293 blank line contains whitespace @@ -104,117 +106,186 @@ ./build/lib/linkage/experiment/titrator.py:59:1: W293 blank line contains whitespace ./build/lib/linkage/experiment/titrator.py:61:47: E231 missing whitespace after ',' ./build/lib/linkage/experiment/titrator.py:62:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:69:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:93:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:102:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:70:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:100:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:109:1: W293 blank line contains whitespace ./build/lib/linkage/models/__init__.py:2:1: F401 'linkage.models.six_state_edta.SixStateEDTA' imported but unused ./build/lib/linkage/models/__init__.py:3:1: F401 'linkage.models.ca_edta.CaEDTA' imported but unused -./build/lib/linkage/models/base.py:4:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/models/base.py:8:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:9:23: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:9:35: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:10:27: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:14:30: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:14:35: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:14:40: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:14:45: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:14:50: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:18:30: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:18:35: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:6:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/models/base.py:9:1: W293 blank line contains whitespace ./build/lib/linkage/models/base.py:19:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:22:80: W292 no newline at end of file +./build/lib/linkage/models/base.py:28:13: E722 do not use bare 'except' +./build/lib/linkage/models/base.py:31:14: W291 trailing whitespace +./build/lib/linkage/models/base.py:38:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:39:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/models/base.py:54:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:69:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/models/base.py:82:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:83:46: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:84:37: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:89:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:92:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/models/base.py:92:38: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:93:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:114:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:124:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:130:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/models/base.py:130:30: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:137:29: W291 trailing whitespace +./build/lib/linkage/models/base.py:142:72: W291 trailing whitespace +./build/lib/linkage/models/base.py:144:65: W291 trailing whitespace +./build/lib/linkage/models/base.py:151:1: C901 '_parse_linkage_docstring' is too complex (14) +./build/lib/linkage/models/base.py:159:44: W291 trailing whitespace +./build/lib/linkage/models/base.py:161:16: W291 trailing whitespace +./build/lib/linkage/models/base.py:175:36: W291 trailing whitespace +./build/lib/linkage/models/base.py:176:71: W291 trailing whitespace +./build/lib/linkage/models/base.py:178:27: W291 trailing whitespace +./build/lib/linkage/models/base.py:179:62: W291 trailing whitespace +./build/lib/linkage/models/base.py:180:69: W291 trailing whitespace +./build/lib/linkage/models/base.py:181:50: W291 trailing whitespace +./build/lib/linkage/models/base.py:182:73: W291 trailing whitespace +./build/lib/linkage/models/base.py:184:36: W291 trailing whitespace +./build/lib/linkage/models/base.py:186:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:193:42: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:196:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:201:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:204:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:218:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:220:67: W291 trailing whitespace +./build/lib/linkage/models/base.py:230:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:235:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:236:39: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:237:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:245:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:246:58: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:256:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:270:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:271:5: E303 too many blank lines (2) +./build/lib/linkage/models/base.py:272:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:280:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:290:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:309:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:310:23: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:310:35: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:313:76: W291 trailing whitespace +./build/lib/linkage/models/base.py:314:57: W291 trailing whitespace +./build/lib/linkage/models/base.py:315:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:318:77: W291 trailing whitespace +./build/lib/linkage/models/base.py:319:79: W291 trailing whitespace +./build/lib/linkage/models/base.py:323:77: W291 trailing whitespace +./build/lib/linkage/models/base.py:324:72: W291 trailing whitespace +./build/lib/linkage/models/base.py:325:73: W291 trailing whitespace +./build/lib/linkage/models/base.py:332:27: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:337:70: W291 trailing whitespace +./build/lib/linkage/models/base.py:338:76: W291 trailing whitespace +./build/lib/linkage/models/base.py:339:55: W291 trailing whitespace +./build/lib/linkage/models/base.py:341:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:345:30: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:350:70: W291 trailing whitespace +./build/lib/linkage/models/base.py:351:78: W291 trailing whitespace +./build/lib/linkage/models/base.py:352:52: W291 trailing whitespace +./build/lib/linkage/models/base.py:358:30: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:359:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:363:74: W291 trailing whitespace +./build/lib/linkage/models/base.py:365:34: W291 trailing whitespace +./build/lib/linkage/models/base.py:372:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:376:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:383:29: W292 no newline at end of file ./build/lib/linkage/models/ca_edta.py:8:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/models/ca_edta.py:10:1: W293 blank line contains whitespace -./build/lib/linkage/models/ca_edta.py:11:5: E303 too many blank lines (2) -./build/lib/linkage/models/ca_edta.py:11:23: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:11:35: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:17:32: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:17:35: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:17:40: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:28:44: E225 missing whitespace around operator -./build/lib/linkage/models/ca_edta.py:29:44: E225 missing whitespace around operator -./build/lib/linkage/models/ca_edta.py:30:44: E225 missing whitespace around operator -./build/lib/linkage/models/ca_edta.py:32:1: W293 blank line contains whitespace -./build/lib/linkage/models/ca_edta.py:36:36: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:37:1: W293 blank line contains whitespace -./build/lib/linkage/models/ca_edta.py:40:1: W293 blank line contains whitespace -./build/lib/linkage/models/ca_edta.py:41:73: W291 trailing whitespace -./build/lib/linkage/models/ca_edta.py:42:75: W291 trailing whitespace -./build/lib/linkage/models/ca_edta.py:44:48: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:47:40: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:54:27: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:54:29: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:54:33: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:62:30: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:63:1: W293 blank line contains whitespace -./build/lib/linkage/models/ca_edta.py:66:42: W292 no newline at end of file +./build/lib/linkage/models/ca_edta.py:13:1: W293 blank line contains whitespace +./build/lib/linkage/models/ca_edta.py:17:1: W293 blank line contains whitespace +./build/lib/linkage/models/ca_edta.py:21:23: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:21:35: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:27:32: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:27:35: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:27:40: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:38:44: E225 missing whitespace around operator +./build/lib/linkage/models/ca_edta.py:39:44: E225 missing whitespace around operator +./build/lib/linkage/models/ca_edta.py:40:44: E225 missing whitespace around operator +./build/lib/linkage/models/ca_edta.py:42:1: W293 blank line contains whitespace +./build/lib/linkage/models/ca_edta.py:46:36: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:47:1: W293 blank line contains whitespace +./build/lib/linkage/models/ca_edta.py:48:58: W291 trailing whitespace +./build/lib/linkage/models/ca_edta.py:50:1: W293 blank line contains whitespace +./build/lib/linkage/models/ca_edta.py:51:73: W291 trailing whitespace +./build/lib/linkage/models/ca_edta.py:52:75: W291 trailing whitespace +./build/lib/linkage/models/ca_edta.py:54:48: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:57:40: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:64:27: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:64:29: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:64:33: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:72:30: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:73:1: W293 blank line contains whitespace +./build/lib/linkage/models/ca_edta.py:77:1: W293 blank line contains whitespace +./build/lib/linkage/models/ca_edta.py:80:13: W292 no newline at end of file ./build/lib/linkage/models/six_state_edta.py:10:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/models/six_state_edta.py:17:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:18:25: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:18:28: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:18:31: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:18:34: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:18:37: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:18:40: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:18:43: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:18:46: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:18:49: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:20:79: W291 trailing whitespace -./build/lib/linkage/models/six_state_edta.py:21:82: W291 trailing whitespace -./build/lib/linkage/models/six_state_edta.py:24:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:30:50: E225 missing whitespace around operator -./build/lib/linkage/models/six_state_edta.py:33:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:35:31: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:35:36: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:35:42: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:35:48: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:35:56: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:35:61: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:38:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:40:47: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:40:53: E225 missing whitespace around operator -./build/lib/linkage/models/six_state_edta.py:40:56: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:40:62: E225 missing whitespace around operator -./build/lib/linkage/models/six_state_edta.py:42:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:45:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:50:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:53:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:54:73: W291 trailing whitespace -./build/lib/linkage/models/six_state_edta.py:56:48: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:60:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:63:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:64:23: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:64:35: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:66:74: W291 trailing whitespace -./build/lib/linkage/models/six_state_edta.py:67:56: W291 trailing whitespace -./build/lib/linkage/models/six_state_edta.py:68:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:75:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:79:79: W291 trailing whitespace -./build/lib/linkage/models/six_state_edta.py:85:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:87:32: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:87:35: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:87:38: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:87:41: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:87:44: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:87:47: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:87:50: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:87:53: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:88:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:94:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:98:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:102:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:105:9: E741 ambiguous variable name 'I' -./build/lib/linkage/models/six_state_edta.py:111:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:113:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:116:30: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:116:35: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:116:40: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:116:45: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:116:50: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:120:30: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:120:35: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:121:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:125:1: W391 blank line at end of file +./build/lib/linkage/models/six_state_edta.py:29:25: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:29:28: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:29:31: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:29:34: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:29:37: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:29:40: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:29:43: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:29:46: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:29:49: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:35:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:36:79: W291 trailing whitespace +./build/lib/linkage/models/six_state_edta.py:37:82: W291 trailing whitespace +./build/lib/linkage/models/six_state_edta.py:40:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:46:50: E225 missing whitespace around operator +./build/lib/linkage/models/six_state_edta.py:49:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:51:31: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:51:36: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:51:42: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:51:48: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:51:56: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:51:61: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:54:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:56:47: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:56:53: E225 missing whitespace around operator +./build/lib/linkage/models/six_state_edta.py:56:56: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:56:62: E225 missing whitespace around operator +./build/lib/linkage/models/six_state_edta.py:58:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:61:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:66:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:69:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:70:73: W291 trailing whitespace +./build/lib/linkage/models/six_state_edta.py:72:48: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:76:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:79:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:80:23: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:80:35: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:82:74: W291 trailing whitespace +./build/lib/linkage/models/six_state_edta.py:83:56: W291 trailing whitespace +./build/lib/linkage/models/six_state_edta.py:84:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:91:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:95:79: W291 trailing whitespace +./build/lib/linkage/models/six_state_edta.py:101:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:103:32: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:103:35: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:103:38: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:103:41: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:103:44: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:103:47: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:103:50: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:103:53: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:104:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:110:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:114:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:118:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:121:9: E741 ambiguous variable name 'I' +./build/lib/linkage/models/six_state_edta.py:127:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:129:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:132:5: E303 too many blank lines (3) +./build/lib/linkage/models/six_state_edta.py:134:30: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:134:35: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:134:40: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:134:45: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:134:50: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:138:30: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:138:35: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:139:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:143:1: W391 blank line at end of file ./build/lib/linkage/organizer/__init__.py:1:1: F401 'linkage.organizer.global_model.GlobalModel' imported but unused ./build/lib/linkage/organizer/__init__.py:1:55: W292 no newline at end of file ./build/lib/linkage/organizer/global_fit.py:10:1: E302 expected 2 blank lines, found 1 @@ -305,68 +376,71 @@ ./build/lib/linkage/organizer/global_model.py:67:1: W293 blank line contains whitespace ./build/lib/linkage/organizer/global_model.py:73:1: W293 blank line contains whitespace ./build/lib/linkage/organizer/global_model.py:81:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:85:15: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:87:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:89:53: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:99:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:100:47: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:115:41: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:122:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:125:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:133:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:135:5: E303 too many blank lines (2) -./build/lib/linkage/organizer/global_model.py:137:69: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:140:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:146:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:149:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:150:61: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:151:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:154:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:164:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:169:49: E127 continuation line over-indented for visual indent -./build/lib/linkage/organizer/global_model.py:170:48: E127 continuation line over-indented for visual indent -./build/lib/linkage/organizer/global_model.py:173:57: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:176:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:178:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:180:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:182:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:183:75: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:184:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:187:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:200:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:202:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:210:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:215:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:220:48: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:224:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:225:5: E303 too many blank lines (2) -./build/lib/linkage/organizer/global_model.py:225:19: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:226:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:86:77: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:88:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:98:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:99:47: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:114:41: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:121:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:124:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:132:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:134:5: E303 too many blank lines (2) +./build/lib/linkage/organizer/global_model.py:136:69: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:139:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:145:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:148:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:149:61: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:150:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:153:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:163:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:168:49: E127 continuation line over-indented for visual indent +./build/lib/linkage/organizer/global_model.py:169:48: E127 continuation line over-indented for visual indent +./build/lib/linkage/organizer/global_model.py:172:57: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:175:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:177:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:179:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:181:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:182:75: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:183:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:186:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:199:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:204:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:213:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:218:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:223:48: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:227:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:228:5: E303 too many blank lines (2) +./build/lib/linkage/organizer/global_model.py:228:19: E231 missing whitespace after ',' ./build/lib/linkage/organizer/global_model.py:229:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:241:78: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:243:59: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:246:56: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:247:53: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:250:40: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:257:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:263:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:275:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:279:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:283:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:287:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:291:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:295:25: E231 missing whitespace after ':' -./build/lib/linkage/organizer/global_model.py:296:27: E231 missing whitespace after ':' -./build/lib/linkage/organizer/global_model.py:297:26: E231 missing whitespace after ':' -./build/lib/linkage/organizer/global_model.py:306:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:309:34: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:315:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:316:36: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:326:52: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:329:52: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:330:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:337:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:337:9: W292 no newline at end of file +./build/lib/linkage/organizer/global_model.py:232:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:244:78: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:246:59: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:249:56: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:250:53: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:253:40: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:260:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:269:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:290:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:297:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:304:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:308:75: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:309:15: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:312:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:316:75: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:317:15: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:320:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:324:25: E231 missing whitespace after ':' +./build/lib/linkage/organizer/global_model.py:325:27: E231 missing whitespace after ':' +./build/lib/linkage/organizer/global_model.py:326:26: E231 missing whitespace after ':' +./build/lib/linkage/organizer/global_model.py:335:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:338:34: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:344:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:345:36: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:355:52: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:358:52: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:359:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:366:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:366:9: W292 no newline at end of file ./src/linkage/__init__.py:2:1: F401 'linkage.experiment.Experiment' imported but unused ./src/linkage/__init__.py:3:1: F401 'linkage.organizer.GlobalModel' imported but unused ./src/linkage/__init__.py:12:52: E231 missing whitespace after ',' @@ -436,21 +510,23 @@ ./src/linkage/experiment/experimental_point.py:102:49: E231 missing whitespace after ',' ./src/linkage/experiment/experimental_point.py:103:42: E231 missing whitespace after ',' ./src/linkage/experiment/experimental_point.py:111:49: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:123:38: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:124:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:144:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:150:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:153:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:154:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:155:5: E303 too many blank lines (2) -./src/linkage/experiment/experimental_point.py:155:24: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:155:35: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:155:41: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:159:17: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:168:41: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:168:76: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:169:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:170:35: W292 no newline at end of file +./src/linkage/experiment/experimental_point.py:124:38: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:125:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:142:75: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:149:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:155:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:159:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:160:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:161:5: E303 too many blank lines (2) +./src/linkage/experiment/experimental_point.py:161:24: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:161:35: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:161:41: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:165:17: W291 trailing whitespace +./src/linkage/experiment/experimental_point.py:174:41: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:174:76: E231 missing whitespace after ',' +./src/linkage/experiment/experimental_point.py:175:1: W293 blank line contains whitespace +./src/linkage/experiment/experimental_point.py:176:35: W292 no newline at end of file +./src/linkage/experiment/titrator.py:6:1: C901 'titrator' is too complex (11) ./src/linkage/experiment/titrator.py:6:1: E302 expected 2 blank lines, found 1 ./src/linkage/experiment/titrator.py:13:55: W291 trailing whitespace ./src/linkage/experiment/titrator.py:14:1: W293 blank line contains whitespace @@ -466,118 +542,186 @@ ./src/linkage/experiment/titrator.py:59:1: W293 blank line contains whitespace ./src/linkage/experiment/titrator.py:61:47: E231 missing whitespace after ',' ./src/linkage/experiment/titrator.py:62:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:69:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:93:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:102:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:70:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:100:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:109:1: W293 blank line contains whitespace ./src/linkage/models/__init__.py:2:1: F401 'linkage.models.six_state_edta.SixStateEDTA' imported but unused ./src/linkage/models/__init__.py:3:1: F401 'linkage.models.ca_edta.CaEDTA' imported but unused -./src/linkage/models/base.py:4:1: E302 expected 2 blank lines, found 1 -./src/linkage/models/base.py:8:1: W293 blank line contains whitespace -./src/linkage/models/base.py:9:23: E231 missing whitespace after ',' -./src/linkage/models/base.py:9:35: E231 missing whitespace after ',' -./src/linkage/models/base.py:10:27: E231 missing whitespace after ',' -./src/linkage/models/base.py:14:30: E231 missing whitespace after ',' -./src/linkage/models/base.py:14:35: E231 missing whitespace after ',' -./src/linkage/models/base.py:14:40: E231 missing whitespace after ',' -./src/linkage/models/base.py:14:45: E231 missing whitespace after ',' -./src/linkage/models/base.py:14:50: E231 missing whitespace after ',' -./src/linkage/models/base.py:18:30: E231 missing whitespace after ',' -./src/linkage/models/base.py:18:35: E231 missing whitespace after ',' +./src/linkage/models/base.py:6:1: E302 expected 2 blank lines, found 1 +./src/linkage/models/base.py:9:1: W293 blank line contains whitespace ./src/linkage/models/base.py:19:1: W293 blank line contains whitespace -./src/linkage/models/base.py:22:80: W292 no newline at end of file +./src/linkage/models/base.py:28:13: E722 do not use bare 'except' +./src/linkage/models/base.py:31:14: W291 trailing whitespace +./src/linkage/models/base.py:38:1: W293 blank line contains whitespace +./src/linkage/models/base.py:39:1: E302 expected 2 blank lines, found 1 +./src/linkage/models/base.py:54:1: W293 blank line contains whitespace +./src/linkage/models/base.py:69:1: E302 expected 2 blank lines, found 1 +./src/linkage/models/base.py:82:1: W293 blank line contains whitespace +./src/linkage/models/base.py:83:46: E231 missing whitespace after ',' +./src/linkage/models/base.py:84:37: E231 missing whitespace after ',' +./src/linkage/models/base.py:89:1: W293 blank line contains whitespace +./src/linkage/models/base.py:92:1: E302 expected 2 blank lines, found 1 +./src/linkage/models/base.py:92:38: E231 missing whitespace after ',' +./src/linkage/models/base.py:93:1: W293 blank line contains whitespace +./src/linkage/models/base.py:114:1: W293 blank line contains whitespace +./src/linkage/models/base.py:124:1: W293 blank line contains whitespace +./src/linkage/models/base.py:130:1: E302 expected 2 blank lines, found 1 +./src/linkage/models/base.py:130:30: E231 missing whitespace after ',' +./src/linkage/models/base.py:137:29: W291 trailing whitespace +./src/linkage/models/base.py:142:72: W291 trailing whitespace +./src/linkage/models/base.py:144:65: W291 trailing whitespace +./src/linkage/models/base.py:151:1: C901 '_parse_linkage_docstring' is too complex (14) +./src/linkage/models/base.py:159:44: W291 trailing whitespace +./src/linkage/models/base.py:161:16: W291 trailing whitespace +./src/linkage/models/base.py:175:36: W291 trailing whitespace +./src/linkage/models/base.py:176:71: W291 trailing whitespace +./src/linkage/models/base.py:178:27: W291 trailing whitespace +./src/linkage/models/base.py:179:62: W291 trailing whitespace +./src/linkage/models/base.py:180:69: W291 trailing whitespace +./src/linkage/models/base.py:181:50: W291 trailing whitespace +./src/linkage/models/base.py:182:73: W291 trailing whitespace +./src/linkage/models/base.py:184:36: W291 trailing whitespace +./src/linkage/models/base.py:186:1: W293 blank line contains whitespace +./src/linkage/models/base.py:193:42: E231 missing whitespace after ',' +./src/linkage/models/base.py:196:1: W293 blank line contains whitespace +./src/linkage/models/base.py:201:1: W293 blank line contains whitespace +./src/linkage/models/base.py:204:1: W293 blank line contains whitespace +./src/linkage/models/base.py:218:1: W293 blank line contains whitespace +./src/linkage/models/base.py:220:67: W291 trailing whitespace +./src/linkage/models/base.py:230:1: W293 blank line contains whitespace +./src/linkage/models/base.py:235:1: W293 blank line contains whitespace +./src/linkage/models/base.py:236:39: E231 missing whitespace after ',' +./src/linkage/models/base.py:237:1: W293 blank line contains whitespace +./src/linkage/models/base.py:245:1: W293 blank line contains whitespace +./src/linkage/models/base.py:246:58: E231 missing whitespace after ',' +./src/linkage/models/base.py:256:1: W293 blank line contains whitespace +./src/linkage/models/base.py:270:1: W293 blank line contains whitespace +./src/linkage/models/base.py:271:5: E303 too many blank lines (2) +./src/linkage/models/base.py:272:1: W293 blank line contains whitespace +./src/linkage/models/base.py:280:1: W293 blank line contains whitespace +./src/linkage/models/base.py:290:1: W293 blank line contains whitespace +./src/linkage/models/base.py:309:1: W293 blank line contains whitespace +./src/linkage/models/base.py:310:23: E231 missing whitespace after ',' +./src/linkage/models/base.py:310:35: E231 missing whitespace after ',' +./src/linkage/models/base.py:313:76: W291 trailing whitespace +./src/linkage/models/base.py:314:57: W291 trailing whitespace +./src/linkage/models/base.py:315:1: W293 blank line contains whitespace +./src/linkage/models/base.py:318:77: W291 trailing whitespace +./src/linkage/models/base.py:319:79: W291 trailing whitespace +./src/linkage/models/base.py:323:77: W291 trailing whitespace +./src/linkage/models/base.py:324:72: W291 trailing whitespace +./src/linkage/models/base.py:325:73: W291 trailing whitespace +./src/linkage/models/base.py:332:27: E231 missing whitespace after ',' +./src/linkage/models/base.py:337:70: W291 trailing whitespace +./src/linkage/models/base.py:338:76: W291 trailing whitespace +./src/linkage/models/base.py:339:55: W291 trailing whitespace +./src/linkage/models/base.py:341:1: W293 blank line contains whitespace +./src/linkage/models/base.py:345:30: E231 missing whitespace after ',' +./src/linkage/models/base.py:350:70: W291 trailing whitespace +./src/linkage/models/base.py:351:78: W291 trailing whitespace +./src/linkage/models/base.py:352:52: W291 trailing whitespace +./src/linkage/models/base.py:358:30: E231 missing whitespace after ',' +./src/linkage/models/base.py:359:1: W293 blank line contains whitespace +./src/linkage/models/base.py:363:74: W291 trailing whitespace +./src/linkage/models/base.py:365:34: W291 trailing whitespace +./src/linkage/models/base.py:372:1: W293 blank line contains whitespace +./src/linkage/models/base.py:376:1: W293 blank line contains whitespace +./src/linkage/models/base.py:383:29: W292 no newline at end of file ./src/linkage/models/ca_edta.py:8:1: E302 expected 2 blank lines, found 1 -./src/linkage/models/ca_edta.py:10:1: W293 blank line contains whitespace -./src/linkage/models/ca_edta.py:11:5: E303 too many blank lines (2) -./src/linkage/models/ca_edta.py:11:23: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:11:35: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:17:32: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:17:35: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:17:40: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:28:44: E225 missing whitespace around operator -./src/linkage/models/ca_edta.py:29:44: E225 missing whitespace around operator -./src/linkage/models/ca_edta.py:30:44: E225 missing whitespace around operator -./src/linkage/models/ca_edta.py:32:1: W293 blank line contains whitespace -./src/linkage/models/ca_edta.py:36:36: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:37:1: W293 blank line contains whitespace -./src/linkage/models/ca_edta.py:38:58: W291 trailing whitespace -./src/linkage/models/ca_edta.py:40:1: W293 blank line contains whitespace -./src/linkage/models/ca_edta.py:41:73: W291 trailing whitespace -./src/linkage/models/ca_edta.py:42:75: W291 trailing whitespace -./src/linkage/models/ca_edta.py:44:48: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:47:40: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:54:27: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:54:29: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:54:33: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:62:30: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:63:1: W293 blank line contains whitespace -./src/linkage/models/ca_edta.py:66:42: W292 no newline at end of file +./src/linkage/models/ca_edta.py:13:1: W293 blank line contains whitespace +./src/linkage/models/ca_edta.py:17:1: W293 blank line contains whitespace +./src/linkage/models/ca_edta.py:21:23: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:21:35: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:27:32: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:27:35: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:27:40: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:38:44: E225 missing whitespace around operator +./src/linkage/models/ca_edta.py:39:44: E225 missing whitespace around operator +./src/linkage/models/ca_edta.py:40:44: E225 missing whitespace around operator +./src/linkage/models/ca_edta.py:42:1: W293 blank line contains whitespace +./src/linkage/models/ca_edta.py:46:36: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:47:1: W293 blank line contains whitespace +./src/linkage/models/ca_edta.py:48:58: W291 trailing whitespace +./src/linkage/models/ca_edta.py:50:1: W293 blank line contains whitespace +./src/linkage/models/ca_edta.py:51:73: W291 trailing whitespace +./src/linkage/models/ca_edta.py:52:75: W291 trailing whitespace +./src/linkage/models/ca_edta.py:54:48: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:57:40: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:64:27: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:64:29: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:64:33: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:72:30: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:73:1: W293 blank line contains whitespace +./src/linkage/models/ca_edta.py:77:1: W293 blank line contains whitespace +./src/linkage/models/ca_edta.py:80:13: W292 no newline at end of file ./src/linkage/models/six_state_edta.py:10:1: E302 expected 2 blank lines, found 1 -./src/linkage/models/six_state_edta.py:17:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:18:25: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:18:28: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:18:31: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:18:34: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:18:37: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:18:40: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:18:43: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:18:46: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:18:49: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:20:79: W291 trailing whitespace -./src/linkage/models/six_state_edta.py:21:82: W291 trailing whitespace -./src/linkage/models/six_state_edta.py:24:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:30:50: E225 missing whitespace around operator -./src/linkage/models/six_state_edta.py:33:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:35:31: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:35:36: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:35:42: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:35:48: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:35:56: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:35:61: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:38:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:40:47: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:40:53: E225 missing whitespace around operator -./src/linkage/models/six_state_edta.py:40:56: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:40:62: E225 missing whitespace around operator -./src/linkage/models/six_state_edta.py:42:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:45:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:50:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:53:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:54:73: W291 trailing whitespace -./src/linkage/models/six_state_edta.py:56:48: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:60:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:63:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:64:23: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:64:35: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:66:74: W291 trailing whitespace -./src/linkage/models/six_state_edta.py:67:56: W291 trailing whitespace -./src/linkage/models/six_state_edta.py:68:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:75:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:79:79: W291 trailing whitespace -./src/linkage/models/six_state_edta.py:85:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:87:32: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:87:35: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:87:38: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:87:41: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:87:44: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:87:47: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:87:50: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:87:53: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:88:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:94:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:98:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:102:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:105:9: E741 ambiguous variable name 'I' -./src/linkage/models/six_state_edta.py:111:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:113:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:116:30: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:116:35: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:116:40: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:116:45: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:116:50: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:120:30: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:120:35: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:121:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:125:1: W391 blank line at end of file +./src/linkage/models/six_state_edta.py:29:25: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:29:28: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:29:31: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:29:34: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:29:37: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:29:40: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:29:43: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:29:46: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:29:49: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:35:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:36:79: W291 trailing whitespace +./src/linkage/models/six_state_edta.py:37:82: W291 trailing whitespace +./src/linkage/models/six_state_edta.py:40:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:46:50: E225 missing whitespace around operator +./src/linkage/models/six_state_edta.py:49:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:51:31: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:51:36: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:51:42: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:51:48: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:51:56: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:51:61: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:54:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:56:47: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:56:53: E225 missing whitespace around operator +./src/linkage/models/six_state_edta.py:56:56: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:56:62: E225 missing whitespace around operator +./src/linkage/models/six_state_edta.py:58:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:61:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:66:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:69:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:70:73: W291 trailing whitespace +./src/linkage/models/six_state_edta.py:72:48: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:76:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:79:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:80:23: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:80:35: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:82:74: W291 trailing whitespace +./src/linkage/models/six_state_edta.py:83:56: W291 trailing whitespace +./src/linkage/models/six_state_edta.py:84:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:91:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:95:79: W291 trailing whitespace +./src/linkage/models/six_state_edta.py:101:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:103:32: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:103:35: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:103:38: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:103:41: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:103:44: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:103:47: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:103:50: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:103:53: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:104:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:110:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:114:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:118:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:121:9: E741 ambiguous variable name 'I' +./src/linkage/models/six_state_edta.py:127:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:129:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:132:5: E303 too many blank lines (3) +./src/linkage/models/six_state_edta.py:134:30: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:134:35: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:134:40: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:134:45: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:134:50: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:138:30: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:138:35: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:139:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:143:1: W391 blank line at end of file ./src/linkage/organizer/__init__.py:1:1: F401 'linkage.organizer.global_model.GlobalModel' imported but unused ./src/linkage/organizer/__init__.py:1:55: W292 no newline at end of file ./src/linkage/organizer/global_model.py:10:1: E302 expected 2 blank lines, found 1 @@ -594,68 +738,71 @@ ./src/linkage/organizer/global_model.py:67:1: W293 blank line contains whitespace ./src/linkage/organizer/global_model.py:73:1: W293 blank line contains whitespace ./src/linkage/organizer/global_model.py:81:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:85:15: W291 trailing whitespace -./src/linkage/organizer/global_model.py:87:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:89:53: W291 trailing whitespace -./src/linkage/organizer/global_model.py:99:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:100:47: W291 trailing whitespace -./src/linkage/organizer/global_model.py:115:41: W291 trailing whitespace -./src/linkage/organizer/global_model.py:122:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:125:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:133:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:135:5: E303 too many blank lines (2) -./src/linkage/organizer/global_model.py:137:69: W291 trailing whitespace -./src/linkage/organizer/global_model.py:140:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:146:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:149:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:150:61: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:151:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:154:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:164:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:169:49: E127 continuation line over-indented for visual indent -./src/linkage/organizer/global_model.py:170:48: E127 continuation line over-indented for visual indent -./src/linkage/organizer/global_model.py:173:57: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:176:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:178:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:180:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:182:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:183:75: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:184:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:187:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:200:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:202:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:210:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:215:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:220:48: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:224:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:225:5: E303 too many blank lines (2) -./src/linkage/organizer/global_model.py:225:19: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:226:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:86:77: W291 trailing whitespace +./src/linkage/organizer/global_model.py:88:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:98:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:99:47: W291 trailing whitespace +./src/linkage/organizer/global_model.py:114:41: W291 trailing whitespace +./src/linkage/organizer/global_model.py:121:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:124:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:132:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:134:5: E303 too many blank lines (2) +./src/linkage/organizer/global_model.py:136:69: W291 trailing whitespace +./src/linkage/organizer/global_model.py:139:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:145:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:148:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:149:61: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:150:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:153:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:163:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:168:49: E127 continuation line over-indented for visual indent +./src/linkage/organizer/global_model.py:169:48: E127 continuation line over-indented for visual indent +./src/linkage/organizer/global_model.py:172:57: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:175:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:177:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:179:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:181:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:182:75: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:183:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:186:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:199:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:204:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:213:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:218:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:223:48: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:227:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:228:5: E303 too many blank lines (2) +./src/linkage/organizer/global_model.py:228:19: E231 missing whitespace after ',' ./src/linkage/organizer/global_model.py:229:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:241:78: W291 trailing whitespace -./src/linkage/organizer/global_model.py:243:59: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:246:56: W291 trailing whitespace -./src/linkage/organizer/global_model.py:247:53: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:250:40: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:257:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:263:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:275:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:279:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:283:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:287:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:291:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:295:25: E231 missing whitespace after ':' -./src/linkage/organizer/global_model.py:296:27: E231 missing whitespace after ':' -./src/linkage/organizer/global_model.py:297:26: E231 missing whitespace after ':' -./src/linkage/organizer/global_model.py:306:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:309:34: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:315:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:316:36: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:326:52: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:329:52: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:330:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:337:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:337:9: W292 no newline at end of file +./src/linkage/organizer/global_model.py:232:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:244:78: W291 trailing whitespace +./src/linkage/organizer/global_model.py:246:59: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:249:56: W291 trailing whitespace +./src/linkage/organizer/global_model.py:250:53: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:253:40: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:260:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:269:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:290:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:297:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:304:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:308:75: W291 trailing whitespace +./src/linkage/organizer/global_model.py:309:15: W291 trailing whitespace +./src/linkage/organizer/global_model.py:312:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:316:75: W291 trailing whitespace +./src/linkage/organizer/global_model.py:317:15: W291 trailing whitespace +./src/linkage/organizer/global_model.py:320:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:324:25: E231 missing whitespace after ':' +./src/linkage/organizer/global_model.py:325:27: E231 missing whitespace after ':' +./src/linkage/organizer/global_model.py:326:26: E231 missing whitespace after ':' +./src/linkage/organizer/global_model.py:335:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:338:34: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:344:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:345:36: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:355:52: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:358:52: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:359:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:366:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:366:9: W292 no newline at end of file ./tests/conftest.py:11:1: E302 expected 2 blank lines, found 1 ./tests/conftest.py:42:63: E231 missing whitespace after ',' ./tests/conftest.py:56:49: E231 missing whitespace after ',' @@ -721,6 +868,345 @@ ./tests/linkage/experiment/test_titrator.py:16:1: W293 blank line contains whitespace ./tests/linkage/experiment/test_titrator.py:19:31: E231 missing whitespace after ',' ./tests/linkage/experiment/test_titrator.py:21:1: W391 blank line at end of file +./tests/linkage/models/test_base.py:14:1: E302 expected 2 blank lines, found 1 +./tests/linkage/models/test_base.py:17:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:17:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:20:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:20:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:23:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:23:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:23:42: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:26:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:26:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:26:42: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:30:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:30:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:30:42: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:30:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:30:50: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:47:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:51:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:53:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:57:32: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:57:37: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:58:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:58:36: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:63:32: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:63:37: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:64:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:64:36: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:105:32: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:105:37: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:105:41: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:105:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:106:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:106:36: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:106:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:110:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:114:32: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:114:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:114:43: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:115:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:115:36: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:115:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:120:32: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:120:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:120:43: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:121:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:121:36: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:121:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:126:32: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:126:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:126:43: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:127:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:127:36: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:127:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:159:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:160:23: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:160:29: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:160:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:160:39: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:161:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:161:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:161:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:161:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:162:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:162:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:162:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:162:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:165:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:165:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:165:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:165:53: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:168:23: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:168:29: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:168:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:168:39: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:169:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:169:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:169:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:169:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:170:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:170:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:170:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:170:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:173:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:173:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:173:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:173:53: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:176:23: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:176:29: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:176:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:176:39: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:176:43: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:177:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:177:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:177:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:177:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:178:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:178:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:178:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:178:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:181:45: E128 continuation line under-indented for visual indent +./tests/linkage/models/test_base.py:182:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:184:23: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:184:29: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:184:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:184:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:184:43: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:185:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:185:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:185:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:185:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:186:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:186:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:186:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:186:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:189:45: E128 continuation line under-indented for visual indent +./tests/linkage/models/test_base.py:190:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:192:23: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:192:29: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:192:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:192:39: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:192:43: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:193:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:193:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:193:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:193:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:194:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:194:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:194:30: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:194:35: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:194:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:197:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:197:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:197:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:197:53: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:197:57: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:200:23: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:200:29: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:200:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:200:39: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:201:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:201:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:201:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:201:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:202:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:202:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:202:30: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:202:35: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:202:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:205:45: E128 continuation line under-indented for visual indent +./tests/linkage/models/test_base.py:206:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:209:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:210:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:210:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:210:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:210:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:211:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:211:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:211:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:211:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:212:25: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:212:29: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:212:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:216:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:218:44: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:218:50: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:218:53: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:218:58: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:219:44: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:219:50: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:219:53: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:219:58: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:220:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:220:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:222:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:222:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:222:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:222:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:223:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:223:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:223:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:223:35: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:224:25: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:224:29: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:224:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:228:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:230:44: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:230:50: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:230:53: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:230:58: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:231:44: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:231:50: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:231:54: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:231:59: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:232:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:232:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:235:5: E303 too many blank lines (2) +./tests/linkage/models/test_base.py:235:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:235:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:235:30: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:235:36: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:235:39: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:235:41: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:236:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:236:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:236:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:236:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:237:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:237:30: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:237:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:237:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:239:40: W291 trailing whitespace +./tests/linkage/models/test_base.py:242:57: E127 continuation line over-indented for visual indent +./tests/linkage/models/test_base.py:248:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:251:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:258:50: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:259:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:259:51: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:259:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:260:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:263:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:263:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:264:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:265:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:266:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:266:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:266:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:267:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:271:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:274:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:284:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:287:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:297:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:300:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:310:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:313:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:323:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:326:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:334:6: E114 indentation is not a multiple of 4 (comment) +./tests/linkage/models/test_base.py:336:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:339:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:347:6: E114 indentation is not a multiple of 4 (comment) +./tests/linkage/models/test_base.py:349:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:352:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:360:6: E114 indentation is not a multiple of 4 (comment) +./tests/linkage/models/test_base.py:360:30: W291 trailing whitespace +./tests/linkage/models/test_base.py:362:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:365:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:371:50: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:372:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:372:51: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:372:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:373:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:376:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:376:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:377:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:378:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:379:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:379:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:379:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:380:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:384:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:387:6: W291 trailing whitespace +./tests/linkage/models/test_base.py:393:50: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:394:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:394:51: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:394:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:395:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:398:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:398:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:399:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:400:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:401:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:401:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:401:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:402:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:404:7: E114 indentation is not a multiple of 4 (comment) +./tests/linkage/models/test_base.py:404:7: E116 unexpected indentation (comment) +./tests/linkage/models/test_base.py:406:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:410:6: W291 trailing whitespace +./tests/linkage/models/test_base.py:418:50: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:419:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:419:51: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:419:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:420:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:423:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:423:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:424:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:425:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:426:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:426:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:426:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:427:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:431:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:435:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:445:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:449:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:457:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:457:37: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:458:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:458:51: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:458:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:459:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:460:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:460:51: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:460:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:461:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:464:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:464:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:465:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:466:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:467:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:467:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:467:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:468:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:472:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:475:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:484:5: E266 too many leading '#' for block comment +./tests/linkage/models/test_base.py:486:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:489:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:497:50: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:498:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:498:51: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:498:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:499:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:504:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:504:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:505:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:506:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:508:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:508:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:509:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:510:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:511:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:512:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:512:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:512:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:513:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:513:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:513:53: W292 no newline at end of file ./tests/linkage/models/test_ca_edta.py:7:1: E302 expected 2 blank lines, found 1 ./tests/linkage/models/test_ca_edta.py:9:27: E231 missing whitespace after ',' ./tests/linkage/models/test_ca_edta.py:9:39: E231 missing whitespace after ',' @@ -778,12 +1264,14 @@ ./tests/linkage/organizer/test_global_model.py:66:1: W293 blank line contains whitespace ./tests/linkage/organizer/test_global_model.py:69:39: E231 missing whitespace after ',' ./tests/linkage/organizer/test_global_model.py:69:48: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:69:53: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:69:68: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:69:73: E231 missing whitespace after ',' ./tests/linkage/organizer/test_global_model.py:70:1: W293 blank line contains whitespace ./tests/linkage/organizer/test_global_model.py:73:39: E231 missing whitespace after ',' ./tests/linkage/organizer/test_global_model.py:73:48: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:73:53: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:73:58: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:73:68: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:73:73: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:73:78: E231 missing whitespace after ',' ./tests/linkage/organizer/test_global_model.py:74:1: W293 blank line contains whitespace ./tests/linkage/organizer/test_global_model.py:77:46: E231 missing whitespace after ',' ./tests/linkage/organizer/test_global_model.py:79:1: E302 expected 2 blank lines, found 1 @@ -812,18 +1300,24 @@ ./tests/linkage/organizer/test_global_model.py:173:5: E303 too many blank lines (2) ./tests/linkage/organizer/test_global_model.py:177:22: E128 continuation line under-indented for visual indent ./tests/linkage/organizer/test_global_model.py:177:47: W292 no newline at end of file -5 E127 continuation line over-indented for visual indent -8 E128 continuation line under-indented for visual indent +4 C901 'titrator' is too complex (11) +4 E114 indentation is not a multiple of 4 (comment) +1 E116 unexpected indentation (comment) +15 E122 continuation line missing indentation or outdented +6 E127 continuation line over-indented for visual indent +11 E128 continuation line under-indented for visual indent 12 E225 missing whitespace around operator -358 E231 missing whitespace after ',' -29 E302 expected 2 blank lines, found 1 -19 E303 too many blank lines (3) +646 E231 missing whitespace after ',' +1 E266 too many leading '#' for block comment +38 E302 expected 2 blank lines, found 1 +22 E303 too many blank lines (3) +2 E722 do not use bare 'except' 2 E741 ambiguous variable name 'I' 14 F401 'linkage.experiment.Experiment' imported but unused 1 F541 f-string is missing placeholders 2 F841 local variable 'args' is assigned to but never used -83 W291 trailing whitespace -17 W292 no newline at end of file -261 W293 blank line contains whitespace +156 W291 trailing whitespace +18 W292 no newline at end of file +344 W293 blank line contains whitespace 3 W391 blank line at end of file -814 +1302 diff --git a/reports/junit/junit.xml b/reports/junit/junit.xml index fd24fa6..739a28b 100644 --- a/reports/junit/junit.xml +++ b/reports/junit/junit.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/linkage/experiment/experiment.py b/src/linkage/experiment/experiment.py index eb68fcc..381c4b8 100644 --- a/src/linkage/experiment/experiment.py +++ b/src/linkage/experiment/experiment.py @@ -38,7 +38,7 @@ def __init__(self, raise ValueError(err) if not issubclass(type(syringe_contents),dict): - err = "syringe_contents should be a dictionary with initial cell concs\n" + err = "syringe_contents should be a dictionary with initial syringe concs\n" raise ValueError(err) # Calculate the total concentrations over the experiment diff --git a/src/linkage/experiment/experimental_point.py b/src/linkage/experiment/experimental_point.py index 0de41f8..ee91cef 100644 --- a/src/linkage/experiment/experimental_point.py +++ b/src/linkage/experiment/experimental_point.py @@ -117,6 +117,7 @@ def __init__(self, obs_key, micro_array, macro_array, + meas_vol_dilution, dh_param_start_idx, dh_param_end_idx): """ @@ -136,6 +137,10 @@ def __init__(self, macro_array : np.ndarray (float) array holding concentrations of all macroscopic species, calculated elsewhere + meas_vol_dilution : float + how much this shot diluted the measurement volume of the cell. This + is calculated using the "titrator" function and corresponds to + (1 - v/V) where v is the injection volume and V is the cell volume dh_param_start_idx : int index of first enthalpy parameter in guesses array dh_param_end_idx : int @@ -148,6 +153,7 @@ def __init__(self, micro_array=micro_array, macro_array=macro_array) + self._meas_vol_dilution = meas_vol_dilution self._dh_param_start_idx = dh_param_start_idx self._dh_param_end_idx = dh_param_end_idx @@ -165,6 +171,6 @@ def calc_value(self,parameters,*args,**kwargs): """ dh_array = parameters[self._dh_param_start_idx:self._dh_param_end_idx] - dC = self._micro_array[self._idx,:] - self._micro_array[self._idx-1,:] + dC = self._micro_array[self._idx,:] - self._micro_array[self._idx-1,:]*self._meas_vol_dilution return np.sum(dC*dh_array) \ No newline at end of file diff --git a/src/linkage/experiment/titrator.py b/src/linkage/experiment/titrator.py index 5b21372..5179a51 100644 --- a/src/linkage/experiment/titrator.py +++ b/src/linkage/experiment/titrator.py @@ -64,6 +64,7 @@ def titrator(cell_contents, out = {} out["injection"] = [] out["volume"] = [] + out["meas_vol_dilution"] = [] for s in species: out[s] = [] @@ -82,9 +83,15 @@ def titrator(cell_contents, else: new_vol = start_vol + injection_array[i] + if len(out["injection"]) == 0: + meas_vol_dilution = 1 + else: + meas_vol_dilution = (1 - injection_array[i]/cell_volume) + # Record current volume and injection out["injection"].append(injection_array[i]) out["volume"].append(new_vol) + out["meas_vol_dilution"].append(meas_vol_dilution) # Update cell concs based on injected titrant for s in species: diff --git a/src/linkage/models/base.py b/src/linkage/models/base.py index d618dab..b8efdad 100644 --- a/src/linkage/models/base.py +++ b/src/linkage/models/base.py @@ -1,22 +1,383 @@ import numpy as np +import re + +def _parse_rxn_side(rxn_side): + + molec = [m.strip() for m in rxn_side.split("+") if m.strip() != ""] + + if len(molec) == 0: + err = f"no molecules found in '{rxn_side}'\n" + raise ValueError(err) + + final_molec = [] + for m in molec: + if len(m.split()) != 1: + err = f"bad molecule '{m}' in '{rxn_side}'\n" + raise ValueError(err) + + with_stoich = m.split("*") + if len(with_stoich) == 1: + final_molec.append(m) + elif len(with_stoich) == 2: + try: + stoich = int(with_stoich[0]) + for _ in range(stoich): + final_molec.append(with_stoich[1]) + except: + err = f"could not coerce '{with_stoich[0]}' in '{rxn_side}' into an integer\n" + raise ValueError(err) + else: + err = "could not parse stoichiometry of '{m}' in '{rxn_side}'\n" + raise ValueError(err) + + final_molec.sort() + + return final_molec + +def _parse_equilibria_field(line): + + first_split = line.split(";") + if len(first_split) != 2: + err = f"could not split '{line}' on ';'\n" + raise ValueError(err) + + K = first_split[1].strip() + if K == "": + err = f"no equilibrium constant on '{line}'\n" + raise ValueError(err) + + if K[0] != "K": + err = f"equilibrium constant on '{line}' should start with 'K'\n" + raise ValueError(err) + + if len(K.split()) != 1: + err = f"equilibrium constant on '{line}' cannot have spaces\n" + raise ValueError(err) + + second_split = first_split[0].split("->") + if len(second_split) != 2: + err = f"could not split '{line}' on '->'\n" + raise ValueError(err) + + reactants = _parse_rxn_side(second_split[0]) + products = _parse_rxn_side(second_split[1]) + + return K, reactants, products + +def _parse_species_field(line): + + first_split = line.split("=") + if len(first_split) != 2: + raise ValueError(f"could not split '{line}' on '='\n") + + macro_species = _parse_rxn_side(first_split[0]) + if len(macro_species) != 1: + err = f"could not parse macrospecies entry '{first_split[0]} on '{line}'\n" + raise ValueError(err) + macro_species = macro_species[0] + + micro_species = _parse_rxn_side(first_split[1]) + + species, counts = np.unique(micro_species,return_counts=True) + to_sort = list(zip(list(species),list(counts))) + to_sort.sort() + + micro_species_names = [m[0] for m in to_sort] + micro_species_stoich = [m[1] for m in to_sort] + + return macro_species, micro_species_names, micro_species_stoich + +def _finalize_microspecies(equilibria,species): + + # Get all micro species seen in the equilibria + micro_species_in_equilibria = [] + for K in equilibria: + micro_species_in_equilibria.extend(equilibria[K][0]) + micro_species_in_equilibria.extend(equilibria[K][1]) + + # get all micro species seen in the species definitions + micro_species_in_species = [] + for s in species: + micro_species_in_species.extend(species[s][0]) + + # Convert species found into sets + micro_species_in_equilibria = set(micro_species_in_equilibria) + micro_species_in_species = set(micro_species_in_species) + + # Check for mismatch between the species in the equilibria and species + # definitions + if not micro_species_in_equilibria == micro_species_in_species: + + err = "mismatch in species between equilibria and species\n" + + only_in_eq = micro_species_in_equilibria - micro_species_in_species + if len(only_in_eq) > 0: + err += f"only in equilibria: {','.join(only_in_eq)}\n" + + only_in_sp = micro_species_in_species - micro_species_in_equilibria + if len(only_in_sp) > 0: + err += f"only in species: {','.join(only_in_sp)}\n" + + raise ValueError(err) + + micro_species = list(micro_species_in_equilibria) + micro_species.sort() + + return micro_species + +def _finalize_species(species,micro_species): + + macro_species = list(species.keys()) + macro_species.sort() + + # Check for species that appears as both a macrospecies and a microspecies + micro_and_macro = set(macro_species).intersection(set(micro_species)) + if len(micro_and_macro): + err = "micro and macrospecies names are not unique\n" + err += f"found in both: {','.join(micro_and_macro)}\n" + raise ValueError(err) + + # Convert species into a dictionary that keys macro species name to + # a list like [(micro_species_1,micro_species_1_stoich), + # (micro_species_2,micro_species_2_stoich),...] + for s in species: + species[s] = list(zip(*species[s])) + + return species, macro_species + + +def _parse_linkage_docstring(docstring): + """ + Extract a thermodynamic linkage model from a docstring. The docstring should + have two sets of fields: equilibria and species. These are parsed like yaml, + where the fields should have ':' at the end and sub-fields are indented. All + other content in the docstring is ignored. Example: + + ``` + Some non-yaml stuff from the docstring. + + equilibria: + X + Y -> Z; K1 # note about reaction 1 + W + X -> Y + Z; K2 # note about reaction 2 + + # comment about the reaction + species: + AT = X + Y + BT = W + Z + ``` + + Rules + ----- + 1. Equilibria lines contain reactants (separated by '+'), a reaction + (specified by '->'), products (separated by '+'), and an equilibrium + constant (separated by ';'). + 2. Species lines contain the macro species (must be single entry), + the definition (separated by '='), and the component micro species + (separated by '+'). + 3. Equilibrium constants and macrospecies must be unique. + 4. Equilibria can *only* contain microspecies, not macrospecies. + 5. Equilibrium constants must start with 'K'. + 6. Names of species and equilibrium constants cannot include spaces. + 7. White space in entries is ignored. + 8. Anything after # is ignored. + """ + + # Figure out how much leader is in front due to python indent + # in class definition + not_whitespace = re.compile("[^\\s]") + front_space = None + for line in docstring.splitlines(): + line = line.split("#")[0] + if line.strip() in ["equilibria:","species:"]: + front_space = not_whitespace.search(line).start() + break + + if front_space is None: + err = "Could not parse reaction description. No 'equilbria:' or \n" + err += "'species:' line found.\n" + raise ValueError(err) + + equilibria = {} + species = {} + + this_field = None + for line in docstring.splitlines(): + + # Split on comment lines + line = line.split("#")[0] + + # Blank line --> no field + if line.strip() == "": + this_field = None + continue + + # If indent level is correct for a new entry + if not_whitespace.match(line[front_space:]): + + # entry looks like 'blah:', not 'blah blah:' or 'blah' + if len(line.split()) == 1 and line.strip()[-1] == ":": + this_field = line.strip()[:-1] + continue + + # otherwise, no field + else: + this_field = None + + # If we are in an equilibria field + if this_field == "equilibria": + + K, reactants, products = _parse_equilibria_field(line) + if K in equilibria: + err = f"equilibrium constant '{K}' appears more than once\n" + raise ValueError(err) + + equilibria[K] = [reactants,products] + + # If we are in a species field + elif this_field == "species": + + macro_species, micro_species_names, micro_species_stoich = _parse_species_field(line) + if macro_species in species: + err = f"macro species '{macro_species}' appears more than once\n" + raise ValueError(err) + + species[macro_species] = [micro_species_names,micro_species_stoich] + + # Not doing anything in this case + else: + continue + + # Make sure we found at least one equilibria field + if len(equilibria) == 0: + err = "no 'equilibria:' entries found\n" + raise ValueError(err) + + # Make sure we found at least one species field + if len(species) == 0: + err = "no 'species:' entries found\n" + raise ValueError(err) + + # Get unique list of micro_species, checking for consistency/sanity + micro_species = _finalize_microspecies(equilibria=equilibria, + species=species) + + # Get unique list of macro_species, checking for consistency/sanity + species, macro_species = _finalize_species(species=species, + micro_species=micro_species) + + + return equilibria, species, micro_species, macro_species + + class BindingModel: + """ + Binding model. Must be subclassed to be used. + """ def __init__(self): - pass + + equilibria, species, micro_species, macro_species = _parse_linkage_docstring(self.__doc__) + + param_from_class = set(self.param_names) + param_from_docstring = set(equilibria.keys()) + if param_from_class != param_from_docstring: + err = "param names from docstring and class definition must match\n" + err += f"from docstring: {','.join(param_from_docstring)}\n" + err += f"from class: {','.join(param_from_class)}\n" + raise AssertionError(err) + + micro_from_class = set(self.micro_species) + micro_from_docstring = set(micro_species) + if micro_from_class != micro_from_docstring: + err = "microspecies from docstring and class definition must match\n" + err += f"from docstring: {','.join(micro_from_docstring)}\n" + err += f"from class: {','.join(micro_from_class)}\n" + raise AssertionError(err) + + macro_from_class = set(self.macro_species) + macro_from_docstring = set(macro_species) + if macro_from_class != macro_from_docstring: + err = "macrospecies from docstring and class definition must match\n" + err += f"from docstring: {','.join(macro_from_docstring)}\n" + err += f"from class: {','.join(macro_from_class)}\n" + raise AssertionError(err) + + self._equilibria = equilibria + self._species = species def get_concs(self,param_array,macro_array): + """ + Function must be defined by subclass. It must take only param_array and + macro_array and return the concentrations of all microspecies given + the parameters and macro species concentrations. + + 1. param_array should be an array of floats holding parameters in the + order defined by the param_names property. + 2. marco_array should be an array of floats holding the macrospecies + inputs in the order defined by the macro_species property. This can + either be an L x N array where 'L' is the number of conditions and + 'N' is the number of macrospecies or simply an 'N'-length array. + 3. The function should return an array of floats holding the calculated + micro species in the order defined by the micro_species property. + This can either be an L x M array where 'L' is the number of + conditions and 'M' is the number of microspecies or simply an + 'M'-length array. + """ + + err = "This method must be redefined by the subclass\n" + raise NotImplementedError(err) + return np.array([],dtype=float) @property def param_names(self): - return np.array(["KI","KE","K1","K2","K3","K4"]) + """ + Parameters defining the model in the order they are read from + `param_array` in the `get_concs` method. These parameters must also + match the equilibria defined in the docstring. + """ + + err = "This property must be redefined by the subclass\n" + raise NotImplementedError(err) + + return np.array(["K1","K2"]) @property def macro_species(self): - return np.array(["AT","CT","ET"]) + """ + Macrospecies within the model in the order they are read from + `macro_array` in the `get_concs` method. These macrospecies must also + match the species defined in the docstring. + """ + + err = "This property must be redefined by the subclass\n" + raise NotImplementedError(err) + + return np.array(["CT","ET"]) @property def micro_species(self): - return np.array(["I", "A", "C", "E", "AC1", "AC2", "AC3", "AC4", "EC"]) \ No newline at end of file + """ + Microspecies from the model in the order they are returned by the + `get_concs` method. These microspecies must also match the species + defined in the docstring. + """ + + err = "This property must be redefined by the subclass\n" + raise NotImplementedError(err) + + return np.array(["C", "E", "EC"]) + + @property + def equilibria(self): + return self._equilibria + + @property + def species(self): + """ + Dictionary keying macro_species to list of tuples representing their + microspecies and the stoichiometries of those microspecies. + """ + return self._species \ No newline at end of file diff --git a/src/linkage/models/ca_edta.py b/src/linkage/models/ca_edta.py index 2b8d887..8bfa1b1 100644 --- a/src/linkage/models/ca_edta.py +++ b/src/linkage/models/ca_edta.py @@ -6,8 +6,18 @@ import warnings class CaEDTA(BindingModel): - + """ + species: + ET = E + EC + CT = C + EC + + equilibria: + E + C -> EC; KE + """ + def __init__(self): + super().__init__() + def get_concs(self,param_array,macro_array): KE = param_array[0] @@ -63,4 +73,8 @@ def macro_species(self): @property def micro_species(self): - return np.array(["C", "E", "EC"]) \ No newline at end of file + return np.array(["C", "E", "EC"]) + + @property + def reactants(self): + pass \ No newline at end of file diff --git a/src/linkage/models/six_state_edta.py b/src/linkage/models/six_state_edta.py index 0655a4f..37e4107 100644 --- a/src/linkage/models/six_state_edta.py +++ b/src/linkage/models/six_state_edta.py @@ -9,14 +9,30 @@ class SixStateEDTA(BindingModel): """ - The `_get_free_c` function finds the polynomial root to get the free - calcium concentration. The `get_concs` function calculates all species - concentrations given $K_{E}$, $K_{1}$, $K_{2}$, $K_{3}$, and $K_{4}$, - as well as the total concentrations of S100A4 dimer, calcium, and EDTA. + equilibria: + E + C -> EC; KE + A -> I; KI + A + C -> AC1; K1 + A + 2*C -> AC2; K2 + A + 3*C -> AC3; K3 + A + 4*C -> AC4; K4 + + species: + ET = E + EC + AT = I + A + 2*AC1 + AC2 + 2*AC3 + AC4 + CT = C + EC + 2*AC1 + 2*AC2 + 6*AC3 + 4*AC4 """ - + + def __init__(self): + super().__init__() + def _get_free_c(self,KI,KE,K1,K2,K3,K4,AT,CT,ET): """ + The `_get_free_c` function finds the polynomial root to get the free + calcium concentration. The `get_concs` function calculates all species + concentrations given $K_{E}$, $K_{1}$, $K_{2}$, $K_{3}$, and $K_{4}$, + as well as the total concentrations of S100A4 dimer, calcium, and EDTA. + Get the free calcium concentration given the equilibrium constants and total concentrations in the system. Private function. Should generally be called by get_concs. @@ -111,6 +127,8 @@ def get_concs(self,param_array,macro_array): return np.array([I, A, C, E, AC1, AC2, AC3, AC4, EC]) + + @property def param_names(self): return np.array(["KI","KE","K1","K2","K3","K4"]) diff --git a/src/linkage/organizer/global_model.py b/src/linkage/organizer/global_model.py index dc7bd79..c7f5989 100644 --- a/src/linkage/organizer/global_model.py +++ b/src/linkage/organizer/global_model.py @@ -81,12 +81,11 @@ def _load_model(self): def _sync_model_and_expt(self): """ - Make sure that all experiments have all concentrations required for the - model. + Make sure that all experiments have concentrations for all macrospecies + used by the model. If an experiment is missing a macro species, set the + concentration of that macrospecies to 0.0 over the whole experiment. """ - # If an experiment is missing a macro species, set the concentration of - # that molecule to 0.0 over whole titration. for expt in self._expt_list: not_in_expt = set(self._bm.macro_species) - set(expt.expt_concs.columns) for missing in not_in_expt: @@ -199,12 +198,16 @@ def _build_point_map(self): denom=den_index) elif obs_info["obs_type"] == "itc": + + meas_vol_dilution = expt.expt_concs.loc[expt.expt_data.index[i], + "meas_vol_dilution"] pt = ITCPoint(idx=i, expt_idx=expt_counter, obs_key=obs, micro_array=self._micro_arrays[-1], macro_array=self._macro_arrays[-1], + meas_vol_dilution=meas_vol_dilution, dh_param_start_idx=self._dh_param_start_idx, dh_param_end_idx=self._dh_param_end_idx + 1) @@ -259,34 +262,60 @@ def model(self,guesses): @property def y_calc(self): + """ + Vector of calculated values. + """ return self._y_calc @property def y_obs(self): + """ + Vector of observed values. + """ return self._y_obs @property def y_stdev(self): + """ + Vector of standard deviations of observed values. + """ return self._y_stdev @property def parameter_names(self): + """ + Names of all fit parameters, in stable order. + """ return self._all_parameter_names @property def parameter_guesses(self): + """ + Parameter values from last run of the model. + """ return self._parameter_guesses @property def model_name(self): + """ + Name of the underlying linkage model used in the analysis. + """ return self._model_name @property def macro_species(self): + """ + Names of all macrospecies, in stable order expected by the linkage + model. + """ return self._bm.macro_species @property def micro_species(self): + """ + Names of all microspecies, in stable order expected by the linkage + model. + """ return self._micro_species @property diff --git a/tests/linkage/models/test_base.py b/tests/linkage/models/test_base.py new file mode 100644 index 0000000..ac8131e --- /dev/null +++ b/tests/linkage/models/test_base.py @@ -0,0 +1,513 @@ + +import pytest + +from linkage.models.base import _parse_rxn_side +from linkage.models.base import _parse_equilibria_field +from linkage.models.base import _parse_species_field +from linkage.models.base import _finalize_microspecies +from linkage.models.base import _finalize_species +from linkage.models.base import _parse_linkage_docstring + + +import numpy as np + +def test__parse_rxn_side(): + + output = _parse_rxn_side("A + B") + assert np.array_equal(output,["A","B"]) + + output = _parse_rxn_side("B + A") + assert np.array_equal(output,["A","B"]) + + output = _parse_rxn_side("B + A + B") + assert np.array_equal(output,["A","B","B"]) + + output = _parse_rxn_side("A + 2*B") + assert np.array_equal(output,["A","B","B"]) + + # some wacky stoich that is legal + output = _parse_rxn_side("A + B + 2*A + A") + assert np.array_equal(output,["A","A","A","A","B"]) + + # no reaction specified + with pytest.raises(ValueError): + output = _parse_rxn_side("") + + # bad species definition (missing + or space in name) + with pytest.raises(ValueError): + output = _parse_rxn_side("A + B C") + + # Bad stoich (not integer) + with pytest.raises(ValueError): + output = _parse_rxn_side("A + 7.2*B") + + # Bad stoich (flipped) + with pytest.raises(ValueError): + output = _parse_rxn_side("A + B*7") + + with pytest.raises(ValueError): + output = _parse_rxn_side("A + 7*7*B") + + +def test__parse_equilibria_field(): + + # basic run + K, react, prod = _parse_equilibria_field("A + B -> C + D; K1") + assert K == "K1" + assert np.array_equal(react,["A","B"]) + assert np.array_equal(prod,["C","D"]) + + # check sorting of products and reactants + K, react, prod = _parse_equilibria_field("B + A -> D + C; K4") + assert K == "K4" + assert np.array_equal(react,["A","B"]) + assert np.array_equal(prod,["C","D"]) + + # no ; + with pytest.raises(ValueError): + K, react, prod = _parse_equilibria_field("B + A -> D + C: K4") + + # multiple no ; + with pytest.raises(ValueError): + K, react, prod = _parse_equilibria_field("B + A -> D + C; K4;") + + # no K + with pytest.raises(ValueError): + K, react, prod = _parse_equilibria_field("B + A -> D + C; ") + + # K with disallowed name + with pytest.raises(ValueError): + K, react, prod = _parse_equilibria_field("B + A -> D + C; AK") + + # K with spaces + with pytest.raises(ValueError): + K, react, prod = _parse_equilibria_field("B + A -> D + C; K 1") + + # no -> + with pytest.raises(ValueError): + K, react, prod = _parse_equilibria_field("B + A + D + C; K1") + + # multiple -> + with pytest.raises(ValueError): + K, react, prod = _parse_equilibria_field("B + A -> D + C -> E + F; K1") + + # bad reactant + with pytest.raises(ValueError): + K, react, prod = _parse_equilibria_field("B C + A -> D + C; K1") + + # bad product + with pytest.raises(ValueError): + K, react, prod = _parse_equilibria_field("B + A -> 7*8*D + C; K1") + + # good, but relatively complicateds + K, react, prod = _parse_equilibria_field("B + 3*A -> D + D + C; Ktest") + assert K == "Ktest" + assert np.array_equal(react,["A","A","A","B"]) + assert np.array_equal(prod,["C","D","D"]) + + +def test__parse_species_field(): + + # basic test + macro, micro, stoich = _parse_species_field("AT = A1 + A2 + A3") + assert macro == "AT" + assert np.array_equal(micro,["A1","A2","A3"]) + assert np.array_equal(stoich,[1,1,1]) + + # Send in some wacky stoichiometries + macro, micro, stoich = _parse_species_field("AT = A1 + A2 + 3*D + A2") + assert macro == "AT" + assert np.array_equal(micro,["A1","A2","D"]) + assert np.array_equal(stoich,[1,2,3]) + + # Make sure it is really grabbing names + macro, micro, stoich = _parse_species_field("XT = A1 + A2 + 11*Q + A2") + assert macro == "XT" + assert np.array_equal(micro,["A1","A2","Q"]) + assert np.array_equal(stoich,[1,2,11]) + + # no = + with pytest.raises(ValueError): + macro, micro, stoich = _parse_species_field("XT A1 + A2 ") + + # multiple = + with pytest.raises(ValueError): + macro, micro, stoich = _parse_species_field("XT = A1 = A2 ") + + # no macrospecies + with pytest.raises(ValueError): + macro, micro, stoich = _parse_species_field(" = A1 + A2") + + # bad macrospecies + with pytest.raises(ValueError): + macro, micro, stoich = _parse_species_field("X1 X2 = A1 + A2") + + # too many macrospecies + with pytest.raises(ValueError): + macro, micro, stoich = _parse_species_field("X1 + X2 = A1 + A2") + + # bad micro species + with pytest.raises(ValueError): + macro, micro, stoich = _parse_species_field("XT = A1 A2") + + # bad micro species + with pytest.raises(ValueError): + macro, micro, stoich = _parse_species_field("XT = A1 + 11.2*A2") + + +def test__finalize_microspecies(): + + equilibria = {"K1":[["A","B"],["C","D"]]} + species = {"AT":[["A","B"],[1,1]], + "CT":[["C","D"],[1,1]]} + micro_species = _finalize_microspecies(equilibria=equilibria, + species=species) + assert np.array_equal(micro_species,["A","B","C","D"]) + + # test sorting + equilibria = {"K1":[["B","A"],["C","D"]]} + species = {"AT":[["A","B"],[1,1]], + "CT":[["D","C"],[1,1]]} + micro_species = _finalize_microspecies(equilibria=equilibria, + species=species) + assert np.array_equal(micro_species,["A","B","C","D"]) + + # extra in reactants + equilibria = {"K1":[["A","B"],["C","D","E"]]} + species = {"AT":[["A","B"],[1,1]], + "CT":[["C","D"],[1,1]]} + with pytest.raises(ValueError): + micro_species = _finalize_microspecies(equilibria=equilibria, + species=species) + + # extra in products + equilibria = {"K1":[["A","B","E"],["C","D"]]} + species = {"AT":[["A","B"],[1,1]], + "CT":[["C","D"],[1,1]]} + with pytest.raises(ValueError): + micro_species = _finalize_microspecies(equilibria=equilibria, + species=species) + + # fix by adding to species + equilibria = {"K1":[["A","B"],["C","D","E"]]} + species = {"AT":[["A","B"],[1,1]], + "CT":[["C","D","E"],[1,1]]} + micro_species = _finalize_microspecies(equilibria=equilibria, + species=species) + assert np.array_equal(micro_species,["A","B","C","D","E"]) + + # extra in species + equilibria = {"K1":[["A","B"],["C","D"]]} + species = {"AT":[["A","B"],[1,1]], + "CT":[["C","D","E"],[1,1]]} + with pytest.raises(ValueError): + micro_species = _finalize_microspecies(equilibria=equilibria, + species=species) + + +def test__finalize_species(): + + species = {"AT":[["A","B"],[1,1]], + "CT":[["C","D"],[1,1]]} + micro_species = ["A","B","C","D"] + + out_species, macro_species = _finalize_species(species=species, + micro_species=micro_species) + + assert len(out_species) == 2 + assert np.array_equal(out_species["AT"],[("A",1),("B",1)]) + assert np.array_equal(out_species["CT"],[("C",1),("D",1)]) + assert np.array_equal(macro_species,["AT","CT"]) + + species = {"AT":[["A","B"],[1,12]], + "XT":[["C","Q"],[12,1]]} + micro_species = ["A","B","C","D"] + + out_species, macro_species = _finalize_species(species=species, + micro_species=micro_species) + + assert len(out_species) == 2 + assert np.array_equal(out_species["AT"],[("A",1),("B",12)]) + assert np.array_equal(out_species["XT"],[("C",12),("Q",1)]) + assert np.array_equal(macro_species,["AT","XT"]) + + + species = {"AT":[["A","B","AT"],[1,1,1]], + "CT":[["C","D"],[1,1]]} + micro_species = ["AT","A","B","C","D"] + + # microspecies same as macrospecies + with pytest.raises(ValueError): + out_species, macro_species = _finalize_species(species=species, + micro_species=micro_species) + + +def test__parse_linkage_docstring(): + + test_str = \ + """ + equilibria: + A + 2*B -> C; K1 + + species: + XT = A + 2*B + C + """ + + equilibria, species, micro_species, macro_species = _parse_linkage_docstring(test_str) + + assert np.array_equal(list(equilibria.keys()),["K1"]) + assert np.array_equal(equilibria["K1"][0],["A","B","B"]) + assert np.array_equal(equilibria["K1"][1],["C"]) + assert len(species.keys()) == 1 + assert list(species.keys())[0] == "XT" + assert np.array_equal(species["XT"],[("A",1), + ("B",2), + ("C",1)]) + assert np.array_equal(micro_species,["A","B","C"]) + assert np.array_equal(macro_species,["XT"]) + + # no correct fields + test_str = \ + """ + equilibriax: + A + 2*B -> C; K1 + + speciesx: + XT = A + 2*B + C + """ + + with pytest.raises(ValueError): + equilibria, species, micro_species, macro_species = _parse_linkage_docstring(test_str) + + # other way to be bad + test_str = \ + """ + equilibria : + A + 2*B -> C; K1 + + species : + XT = A + 2*B + C + """ + + with pytest.raises(ValueError): + equilibria, species, micro_species, macro_species = _parse_linkage_docstring(test_str) + + # another way to be bad + test_str = \ + """ + equilibria test: + A + 2*B -> C; K1 + + species test: + XT = A + 2*B + C + """ + + with pytest.raises(ValueError): + equilibria, species, micro_species, macro_species = _parse_linkage_docstring(test_str) + + # should fail because no equilibria entry + test_str = \ + """ + equilibria: + # A + 2*B -> C; K1 + + species: + XT = A + 2*B + C + """ + + with pytest.raises(ValueError): + equilibria, species, micro_species, macro_species = _parse_linkage_docstring(test_str) + + # should fail because no species entry + test_str = \ + """ + equilibria: + A + 2*B -> C; K1 + + species: + # XT = A + 2*B + C + """ + + with pytest.raises(ValueError): + equilibria, species, micro_species, macro_species = _parse_linkage_docstring(test_str) + + # should fail because of messed up indentation + test_str = \ + """ + equilibria: + A + 2*B -> C; K1 + + species: + XT = A + 2*B + C + """ + + with pytest.raises(ValueError): + equilibria, species, micro_species, macro_species = _parse_linkage_docstring(test_str) + + # should fail because of messed up indentation + test_str = \ + """ + equilibria: + A + 2*B -> C; K1 + + species: + XT = A + 2*B + C + """ + + with pytest.raises(ValueError): + equilibria, species, micro_species, macro_species = _parse_linkage_docstring(test_str) + + # should be fine because + test_str = \ + """ + equilibria: + A + 2*B -> C; K1 + + species: + XT = A + 2*B + C + """ + + equilibria, species, micro_species, macro_species = _parse_linkage_docstring(test_str) + assert np.array_equal(list(equilibria.keys()),["K1"]) + assert np.array_equal(equilibria["K1"][0],["A","B","B"]) + assert np.array_equal(equilibria["K1"][1],["C"]) + assert len(species.keys()) == 1 + assert list(species.keys())[0] == "XT" + assert np.array_equal(species["XT"],[("A",1), + ("B",2), + ("C",1)]) + assert np.array_equal(micro_species,["A","B","C"]) + assert np.array_equal(macro_species,["XT"]) + + # should be fine + test_str = \ + """ + equilibria: + A + 2*B -> C; K1 + # + species: + XT = A + 2*B + C + """ + + equilibria, species, micro_species, macro_species = _parse_linkage_docstring(test_str) + assert np.array_equal(list(equilibria.keys()),["K1"]) + assert np.array_equal(equilibria["K1"][0],["A","B","B"]) + assert np.array_equal(equilibria["K1"][1],["C"]) + assert len(species.keys()) == 1 + assert list(species.keys())[0] == "XT" + assert np.array_equal(species["XT"],[("A",1), + ("B",2), + ("C",1)]) + assert np.array_equal(micro_species,["A","B","C"]) + assert np.array_equal(macro_species,["XT"]) + + # should be fine, lots of valid comments + test_str = \ + """ + # comment! + equilibria:#comment + A + 2*B -> C; K1 #comment here + # + species: #comment + XT = A + 2*B + C#comment + + ###### + """ + + equilibria, species, micro_species, macro_species = _parse_linkage_docstring(test_str) + assert np.array_equal(list(equilibria.keys()),["K1"]) + assert np.array_equal(equilibria["K1"][0],["A","B","B"]) + assert np.array_equal(equilibria["K1"][1],["C"]) + assert len(species.keys()) == 1 + assert list(species.keys())[0] == "XT" + assert np.array_equal(species["XT"],[("A",1), + ("B",2), + ("C",1)]) + assert np.array_equal(micro_species,["A","B","C"]) + assert np.array_equal(macro_species,["XT"]) + + # should fail because of duplicated K1 + test_str = \ + """ + equilibria: + A + 2*B -> C; K1 + A + 2*B -> C; K1 + + species: + XT = A + 2*B + C + """ + + with pytest.raises(ValueError): + equilibria, species, micro_species, macro_species = _parse_linkage_docstring(test_str) + + # should work because reaction now has diff names + test_str = \ + """ + equilibria: + A + 2*B -> C; K1 + A + 2*B -> C; K2 + + species: + XT = A + 2*B + C + """ + + equilibria, species, micro_species, macro_species = _parse_linkage_docstring(test_str) + keys = list(equilibria.keys()) + keys.sort() + assert np.array_equal(keys,["K1","K2"]) + assert np.array_equal(equilibria["K1"][0],["A","B","B"]) + assert np.array_equal(equilibria["K1"][1],["C"]) + assert np.array_equal(equilibria["K2"][0],["A","B","B"]) + assert np.array_equal(equilibria["K2"][1],["C"]) + assert len(species.keys()) == 1 + assert list(species.keys())[0] == "XT" + assert np.array_equal(species["XT"],[("A",1), + ("B",2), + ("C",1)]) + assert np.array_equal(micro_species,["A","B","C"]) + assert np.array_equal(macro_species,["XT"]) + + # should fail because of duplicated XT + test_str = \ + """ + equilibria: + A + 2*B -> C; K1 + + species: + XT = A + 2*B + C + XT = A + 2*B + C + """ + + with pytest.raises(ValueError): + equilibria, species, micro_species, macro_species = _parse_linkage_docstring(test_str) + + ## should work because of YT + test_str = \ + """ + equilibria: + A + 2*B -> C; K1 + + species: + XT = A + 2*B + C + YT = A + B + B + B + 2*C + """ + + equilibria, species, micro_species, macro_species = _parse_linkage_docstring(test_str) + + assert np.array_equal(list(equilibria.keys()),["K1"]) + assert np.array_equal(equilibria["K1"][0],["A","B","B"]) + assert np.array_equal(equilibria["K1"][1],["C"]) + assert len(species.keys()) == 2 + keys = list(species.keys()) + keys.sort() + assert keys[0] == "XT" + assert np.array_equal(species["XT"],[("A",1), + ("B",2), + ("C",1)]) + assert keys[1] == "YT" + assert np.array_equal(species["YT"],[("A",1), + ("B",3), + ("C",2)]) + + assert np.array_equal(micro_species,["A","B","C"]) + assert np.array_equal(macro_species,["XT","YT"]) \ No newline at end of file diff --git a/tests/linkage/organizer/test_global_model.py b/tests/linkage/organizer/test_global_model.py index 3c5bb2d..19aed36 100644 --- a/tests/linkage/organizer/test_global_model.py +++ b/tests/linkage/organizer/test_global_model.py @@ -66,11 +66,11 @@ def test_GlobalModel__sync_model_and_expt(fake_spec_and_itc_data): # Make sure array starts without AT assert np.array_equal(this_expt_list[1].expt_concs.columns, - ["injection","volume","CT","ET"]) + ["injection","volume","meas_vol_dilution","CT","ET"]) # make sure we added AT assert np.array_equal(gf._expt_list[1].expt_concs.columns, - ["injection","volume","CT","ET","AT"]) + ["injection","volume","meas_vol_dilution","CT","ET","AT"]) num_points = len(gf._expt_list[1].expt_concs["AT"]) assert np.array_equal(gf._expt_list[1].expt_concs["AT"], From 3f2577907e214357cc61617e9cb40f73b3c4afc2 Mon Sep 17 00:00:00 2001 From: Michael Harms Date: Thu, 25 Jul 2024 21:42:15 -0700 Subject: [PATCH 06/17] added tests --- docs/badges/coverage-badge.svg | 2 +- docs/badges/tests-badge.svg | 2 +- reports/flake.txt | 29 ++++++++++++++++---- reports/junit/junit.xml | 2 +- src/linkage/experiment/experimental_point.py | 2 +- tests/linkage/models/test_ca_edta.py | 19 ++++++++++++- 6 files changed, 46 insertions(+), 10 deletions(-) diff --git a/docs/badges/coverage-badge.svg b/docs/badges/coverage-badge.svg index 4ed2f95..2ce7beb 100644 --- a/docs/badges/coverage-badge.svg +++ b/docs/badges/coverage-badge.svg @@ -1 +1 @@ -coverage: 91.73%coverage91.73% \ No newline at end of file +coverage: 91.90%coverage91.90% \ No newline at end of file diff --git a/docs/badges/tests-badge.svg b/docs/badges/tests-badge.svg index 94169cd..56180de 100644 --- a/docs/badges/tests-badge.svg +++ b/docs/badges/tests-badge.svg @@ -1 +1 @@ -tests: 15tests15 \ No newline at end of file +tests: 16tests16 \ No newline at end of file diff --git a/reports/flake.txt b/reports/flake.txt index 124a480..059e062 100644 --- a/reports/flake.txt +++ b/reports/flake.txt @@ -1247,7 +1247,26 @@ ./tests/linkage/models/test_ca_edta.py:64:36: E231 missing whitespace after ',' ./tests/linkage/models/test_ca_edta.py:64:53: E231 missing whitespace after ',' ./tests/linkage/models/test_ca_edta.py:64:66: E231 missing whitespace after ',' -./tests/linkage/models/test_ca_edta.py:64:82: W292 no newline at end of file +./tests/linkage/models/test_ca_edta.py:66:1: E302 expected 2 blank lines, found 1 +./tests/linkage/models/test_ca_edta.py:71:43: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:71:49: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:71:52: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:71:58: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:72:43: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:72:49: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:72:52: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:72:58: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:73:1: W293 blank line contains whitespace +./tests/linkage/models/test_ca_edta.py:75:49: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:75:54: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:76:49: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:79:41: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:80:43: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:80:49: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:81:43: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:81:48: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:81:52: E231 missing whitespace after ',' +./tests/linkage/models/test_ca_edta.py:81:59: W292 no newline at end of file ./tests/linkage/organizer/test_global_model.py:14:1: E302 expected 2 blank lines, found 1 ./tests/linkage/organizer/test_global_model.py:21:1: W293 blank line contains whitespace ./tests/linkage/organizer/test_global_model.py:25:31: E231 missing whitespace after ',' @@ -1307,9 +1326,9 @@ 6 E127 continuation line over-indented for visual indent 11 E128 continuation line under-indented for visual indent 12 E225 missing whitespace around operator -646 E231 missing whitespace after ',' +663 E231 missing whitespace after ',' 1 E266 too many leading '#' for block comment -38 E302 expected 2 blank lines, found 1 +39 E302 expected 2 blank lines, found 1 22 E303 too many blank lines (3) 2 E722 do not use bare 'except' 2 E741 ambiguous variable name 'I' @@ -1318,6 +1337,6 @@ 2 F841 local variable 'args' is assigned to but never used 156 W291 trailing whitespace 18 W292 no newline at end of file -344 W293 blank line contains whitespace +345 W293 blank line contains whitespace 3 W391 blank line at end of file -1302 +1321 diff --git a/reports/junit/junit.xml b/reports/junit/junit.xml index 739a28b..2195653 100644 --- a/reports/junit/junit.xml +++ b/reports/junit/junit.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/linkage/experiment/experimental_point.py b/src/linkage/experiment/experimental_point.py index ee91cef..f59fb93 100644 --- a/src/linkage/experiment/experimental_point.py +++ b/src/linkage/experiment/experimental_point.py @@ -58,7 +58,7 @@ def __init__(self, micro_array, macro_array, obs_mask, - denom,): + denom): """ Initialize a spectroscopic data point. diff --git a/tests/linkage/models/test_ca_edta.py b/tests/linkage/models/test_ca_edta.py index 30e9028..5ea0f5c 100644 --- a/tests/linkage/models/test_ca_edta.py +++ b/tests/linkage/models/test_ca_edta.py @@ -61,4 +61,21 @@ def _check_with_log(bm,param_array,macro_array,expected_values): with pytest.warns(): concs = bm.get_concs(param_array=np.array([np.nan]), macro_array=np.array([np.nan,np.nan])) - assert np.array_equal(concs,np.nan*np.ones(3,dtype=float),equal_nan=True) \ No newline at end of file + assert np.array_equal(concs,np.nan*np.ones(3,dtype=float),equal_nan=True) + +def test_CaEDTA_properties(): + + # these properties are loaded from the docstring + bm = CaEDTA() + assert len(bm.species) == 2 + assert np.array_equal(bm.species["CT"],[("C",1),("EC",1)]) + assert np.array_equal(bm.species["ET"],[("E",1),("EC",1)]) + + assert len(bm.equilibria) == 1 + assert np.array_equal(bm.equilibria["KE"][0],["C","E"]) + assert np.array_equal(bm.equilibria["KE"][1],["EC"]) + + # built in properties + assert np.array_equal(bm.param_names,["KE"]) + assert np.array_equal(bm.macro_species,["CT","ET"]) + assert np.array_equal(bm.micro_species,["C","E","EC"]) \ No newline at end of file From 4de9d4d2d3973415e01afb3c5d3407837c614210 Mon Sep 17 00:00:00 2001 From: Michael Harms Date: Mon, 29 Jul 2024 10:56:33 -0700 Subject: [PATCH 07/17] removed redundant root finding code; cleaned up --- src/linkage/models/base.py | 119 +++++++++++++++++++-------- src/linkage/models/ca_edta.py | 37 ++------- src/linkage/models/six_state_edta.py | 36 ++------ tests/linkage/models/test_base.py | 65 ++++++++++++++- 4 files changed, 162 insertions(+), 95 deletions(-) diff --git a/src/linkage/models/base.py b/src/linkage/models/base.py index b8efdad..6dcca65 100644 --- a/src/linkage/models/base.py +++ b/src/linkage/models/base.py @@ -2,6 +2,7 @@ import numpy as np import re +import warnings def _parse_rxn_side(rxn_side): @@ -149,40 +150,6 @@ def _finalize_species(species,micro_species): def _parse_linkage_docstring(docstring): - """ - Extract a thermodynamic linkage model from a docstring. The docstring should - have two sets of fields: equilibria and species. These are parsed like yaml, - where the fields should have ':' at the end and sub-fields are indented. All - other content in the docstring is ignored. Example: - - ``` - Some non-yaml stuff from the docstring. - - equilibria: - X + Y -> Z; K1 # note about reaction 1 - W + X -> Y + Z; K2 # note about reaction 2 - - # comment about the reaction - species: - AT = X + Y - BT = W + Z - ``` - - Rules - ----- - 1. Equilibria lines contain reactants (separated by '+'), a reaction - (specified by '->'), products (separated by '+'), and an equilibrium - constant (separated by ';'). - 2. Species lines contain the macro species (must be single entry), - the definition (separated by '='), and the component micro species - (separated by '+'). - 3. Equilibrium constants and macrospecies must be unique. - 4. Equilibria can *only* contain microspecies, not macrospecies. - 5. Equilibrium constants must start with 'K'. - 6. Names of species and equilibrium constants cannot include spaces. - 7. White space in entries is ignored. - 8. Anything after # is ignored. - """ # Figure out how much leader is in front due to python indent # in class definition @@ -274,9 +241,52 @@ def _parse_linkage_docstring(docstring): class BindingModel: """ Binding model. Must be subclassed to be used. + + Subclass must define the get_concs method and three properties: param_names, + macro_species, and micro_species. See the docstrings on those functions for + details. + + The docstring for the subclass must describe the thermodynamic model. It + should have two sets of fields: equilibria and species. These are parsed + like yaml, where the fields should have ':' at the end and sub-fields are + indented. All other content in the docstring is ignored. Example: + + ``` + This is some non-yaml stuff from the docstring. + + equilibria: + X + Y -> Z; K1 # note about reaction 1 + W + X -> Y + Z; K2 # note about reaction 2 + + # comment about the reaction + species: + AT = X + Y + BT = W + Z + + More non-yaml stuff. + ``` + + Rules for defining the equilibria + --------------------------------- + + 1. Equilibria lines contain reactants (separated by '+'), a reaction + (specified by '->'), products (separated by '+'), and an equilibrium + constant (separated by ';'). + 2. Species lines contain the macro species (must be single entry), + the definition (separated by '='), and the component micro species + (separated by '+'). + 3. Equilibrium constants and macrospecies must be unique. + 4. Equilibria can only contain microspecies, not macrospecies. + 5. Equilibrium constants must start with 'K'. + 6. Names of species and equilibrium constants cannot include spaces. + 7. White space in entries is ignored. + 8. Anything after # is ignored. """ def __init__(self): + """ + Initialize the class. + """ equilibria, species, micro_species, macro_species = _parse_linkage_docstring(self.__doc__) @@ -306,6 +316,47 @@ def __init__(self): self._equilibria = equilibria self._species = species + + def _get_real_root(self,roots,upper_bounds=[]): + """ + Get the real root between 0 and upper_bounds. + + Parameters + ---------- + roots : numpy.ndarray + numpy array with roots to check + upper_bounds : list-like + list of upper bounds against which to check root. + """ + + to_check = [np.isreal(roots), + roots >= 0] + if len(upper_bounds) > 0: + to_check.append(roots <= np.min(upper_bounds)) + + # Get real root that that has value >= 0 and below upper bounds + mask = np.logical_and.reduce(to_check) + solution = np.unique(roots[mask]) + + # No root matches condition. Warn and return np.nan. + if len(solution) == 0: + warnings.warn("no roots found\n") + return np.nan + + # Multiple roots match conditions. Warn and return np.nan + if len(solution) > 1: + + # Check whether the all roots are numerically close and thus + # arise from float imprecision. If really have multiple roots, + # return np.nan for all concentrations + close_mask = np.isclose(solution[0],solution) + if np.sum(close_mask) != len(solution): + warnings.warn("multiple roots found\n") + return np.nan + + # Return real component + return np.real(solution[0]) + def get_concs(self,param_array,macro_array): """ diff --git a/src/linkage/models/ca_edta.py b/src/linkage/models/ca_edta.py index 8bfa1b1..d33dd6f 100644 --- a/src/linkage/models/ca_edta.py +++ b/src/linkage/models/ca_edta.py @@ -3,21 +3,16 @@ import numpy as np -import warnings - class CaEDTA(BindingModel): """ + equilibria: + E + C -> EC; KE + species: ET = E + EC CT = C + EC - - equilibria: - E + C -> EC; KE """ - def __init__(self): - super().__init__() - def get_concs(self,param_array,macro_array): KE = param_array[0] @@ -33,31 +28,11 @@ def get_concs(self,param_array,macro_array): s = np.sqrt(b**2 - 4*c) roots = np.array([(-b + s)/2, (-b - s)/2]) - # Get real root that has concentration <= CT and <= ET - mask = np.logical_and.reduce((np.isreal(roots), - roots>=0, - roots<=CT, - roots<=ET)) - solution = np.unique(roots[mask]) + # EC is the real root between 0->ET and 0->CT + EC = self._get_real_root(roots=roots, + upper_bounds=[ET,CT]) - # No real root between 0 and CT. Return np.nan for all concentrations - if len(solution) == 0: - warnings.warn("no roots found\n") - return np.nan*np.ones(3,dtype=float) - - # Multiple real roots between 0 and CT, 0 and ET. - if len(solution) > 1: - - # Check whether the all roots are numerically close and thus - # arise from float imprecision. If really have multiple roots, - # return np.nan for all concentrations - close_mask = np.isclose(solution[0],solution) - if np.sum(close_mask) != len(solution): - warnings.warn("multiple roots found\n") - return np.nan*np.ones(3,dtype=float) - # Get species - EC = np.real(solution[0]) C = CT - EC E = ET - EC diff --git a/src/linkage/models/six_state_edta.py b/src/linkage/models/six_state_edta.py index 37e4107..5b21411 100644 --- a/src/linkage/models/six_state_edta.py +++ b/src/linkage/models/six_state_edta.py @@ -5,7 +5,6 @@ import numpy as np -import warnings class SixStateEDTA(BindingModel): """ @@ -23,9 +22,6 @@ class SixStateEDTA(BindingModel): CT = C + EC + 2*AC1 + 2*AC2 + 6*AC3 + 4*AC4 """ - def __init__(self): - super().__init__() - def _get_free_c(self,KI,KE,K1,K2,K3,K4,AT,CT,ET): """ The `_get_free_c` function finds the polynomial root to get the free @@ -51,31 +47,13 @@ def _get_free_c(self,KI,KE,K1,K2,K3,K4,AT,CT,ET): coef = np.array([alpha,beta,gamma,delta,epsilon,zeta,eta]) P = np.polynomial.Polynomial(coef=coef) roots = P.roots() - - # The solution is a real root between 0 and CT. Pull this out. - mask = np.logical_and(np.isreal(roots),roots>=0,roots<=CT) - solution = np.unique(roots[mask]) - - # There should be one unique solution; check for this. If this does - # not succeed, return np.nan - - # No real root between 0 and CT - if len(solution) == 0: - warnings.warn("no roots found\n") - return np.nan - - # Multiple real roots between 0 and CT - if len(solution) > 1: - - # Check whether the all roots are numerically close and thus - # arise from float imprecision - close_mask = np.isclose(solution[0],solution) - if np.sum(close_mask) != len(solution): - warnings.warn("multiple roots found\n") - return np.nan - - # Return free calcium - return np.real(solution[0]) + + # Get real root between 0 and CT + root = self._get_real_root(roots=roots, + upper_bounds=[CT]) + + return root + def get_concs(self,param_array,macro_array): """ diff --git a/tests/linkage/models/test_base.py b/tests/linkage/models/test_base.py index ac8131e..4b207cd 100644 --- a/tests/linkage/models/test_base.py +++ b/tests/linkage/models/test_base.py @@ -7,6 +7,7 @@ from linkage.models.base import _finalize_microspecies from linkage.models.base import _finalize_species from linkage.models.base import _parse_linkage_docstring +from linkage.models.base import BindingModel import numpy as np @@ -510,4 +511,66 @@ def test__parse_linkage_docstring(): ("C",2)]) assert np.array_equal(micro_species,["A","B","C"]) - assert np.array_equal(macro_species,["XT","YT"]) \ No newline at end of file + assert np.array_equal(macro_species,["XT","YT"]) + + +def test_BindingModel__get_real_root(): + + # Should work + roots = np.array([-1,1]) + root = BindingModel._get_real_root(BindingModel, + roots=roots, + upper_bounds=[2]) + assert root == 1 + + # Root too high + roots = np.array([-1,1]) + with pytest.warns(): + root = BindingModel._get_real_root(BindingModel, + roots=roots, + upper_bounds=[0.1]) + assert np.isnan(root) + + # No real root + roots = np.array([1+2j,1+3j]) + with pytest.warns(): + root = BindingModel._get_real_root(BindingModel, + roots=roots, + upper_bounds=[10]) + assert np.isnan(root) + + # No positive root + roots = np.array([-1,-5]) + with pytest.warns(): + root = BindingModel._get_real_root(BindingModel, + roots=roots, + upper_bounds=[10]) + assert np.isnan(root) + + # Complicated root that works + roots = np.array([-1,-5,1,20,1+3j]) + root = BindingModel._get_real_root(BindingModel, + roots=roots, + upper_bounds=[3,5]) + assert root == 1 + + # Complicated root that will give multiple allowed values -- fail + roots = np.array([-1,-5,1,20,1+3j]) + with pytest.warns(): + root = BindingModel._get_real_root(BindingModel, + roots=roots, + upper_bounds=[22,50]) + assert np.isnan(root) + + # no upper bound + roots = np.array([-1,-5,1,1+3j]) + root = BindingModel._get_real_root(BindingModel, + roots=roots) + assert root == 1 + + # Multiple close roots + roots = np.array([-1,-5,1,1 + 1e-25]) + root = BindingModel._get_real_root(BindingModel, + roots=roots, + upper_bounds=[2]) + assert root == 1 From e93eb0e1375f0a4dbbc5aab8c1afdb84a55f5b1b Mon Sep 17 00:00:00 2001 From: Michael Harms Date: Mon, 29 Jul 2024 13:09:36 -0700 Subject: [PATCH 08/17] changed enthalpy calc from species to rxns --- src/linkage/experiment/experimental_point.py | 176 ------------------ src/linkage/experiment/point/__init__.py | 1 + .../experiment/point/experimental_point.py | 45 +++++ src/linkage/experiment/point/itc_point.py | 93 +++++++++ src/linkage/experiment/point/spec_point.py | 65 +++++++ src/linkage/organizer/global_model.py | 33 +++- .../point/test_experimental_point.py | 26 +++ .../experiment/point/test_itc_point.py | 123 ++++++++++++ .../experiment/point/test_spec_point.py | 111 +++++++++++ tests/linkage/organizer/test_global_model.py | 22 ++- 10 files changed, 509 insertions(+), 186 deletions(-) delete mode 100644 src/linkage/experiment/experimental_point.py create mode 100644 src/linkage/experiment/point/__init__.py create mode 100644 src/linkage/experiment/point/experimental_point.py create mode 100644 src/linkage/experiment/point/itc_point.py create mode 100644 src/linkage/experiment/point/spec_point.py create mode 100644 tests/linkage/experiment/point/test_experimental_point.py create mode 100644 tests/linkage/experiment/point/test_itc_point.py create mode 100644 tests/linkage/experiment/point/test_spec_point.py diff --git a/src/linkage/experiment/experimental_point.py b/src/linkage/experiment/experimental_point.py deleted file mode 100644 index f59fb93..0000000 --- a/src/linkage/experiment/experimental_point.py +++ /dev/null @@ -1,176 +0,0 @@ -import numpy as np - -class ExperimentalPoint: - """ - Class for storing an individual experimental data point. Should be sub- - classed. - """ - - def __init__(self, - idx, - expt_idx, - obs_key, - micro_array, - macro_array): - """ - Should be sub-classed. - """ - - self._idx = idx - self._expt_idx = expt_idx - self._obs_key = obs_key - self._micro_array = micro_array - self._macro_array = macro_array - - @property - def idx(self): - """ - Index of point in experimental array. - """ - return self._idx - - @property - def expt_idx(self): - """ - Index of experiment. - """ - return self._expt_idx - - @property - def obs_key(self): - """ - Name of observable. - """ - return self._obs_key - - - -class SpecPoint(ExperimentalPoint): - """ - Class holds experimental data for an individual spectroscopic - experimental data point and how it links to the binding model. - """ - - def __init__(self, - idx, - expt_idx, - obs_key, - micro_array, - macro_array, - obs_mask, - denom): - """ - Initialize a spectroscopic data point. - - Parameters - ---------- - idx : int - index of point in the experimental array - expt_idx : int - index of the experiment itself (allowing multiple experiments) - obs_key : str - key pointing to observable from the experiment - micro_array : np.ndarray (float) - array holding concentrations of all microscopic species, calculated - elsewhere - macro_array : np.ndarray (float) - array holding concentrations of all macroscopic species, calculated - elsewhere - obs_mask : np.ndarray (bool or int) - mask that grabs microscopic species from micro_array that correspond - to the numerator when calculating the observable - denom : int - index of the macro species that should be used as the denominator - for the observable calculation - """ - - super().__init__(idx=idx, - expt_idx=expt_idx, - obs_key=obs_key, - micro_array=micro_array, - macro_array=macro_array) - - self._obs_mask = obs_mask - self._denom = denom - - def calc_value(self,*args,**kwargs): - """ - Calculate the observable given the estimated concentrations of all - species. *args and **kwargs are ignored. - """ - - num = np.sum(self._micro_array[self._idx,self._obs_mask]) - den = self._macro_array[self._idx,self._denom] - - return num/den - - -class ITCPoint(ExperimentalPoint): - """ - Class holds experimental data for an individual ITC experimental data point - and how it links to the thermodynamic model. - """ - - def __init__(self, - idx, - expt_idx, - obs_key, - micro_array, - macro_array, - meas_vol_dilution, - dh_param_start_idx, - dh_param_end_idx): - """ - Initialize an ITC data point. - - Parameters - ---------- - idx : int - index of point in the experimental array - expt_idx : int - index of the experiment itself (allowing multiple experiments) - obs_key : str - key pointing to observable from the experiment - micro_array : np.ndarray (float) - array holding concentrations of all microscopic species, calculated - elsewhere - macro_array : np.ndarray (float) - array holding concentrations of all macroscopic species, calculated - elsewhere - meas_vol_dilution : float - how much this shot diluted the measurement volume of the cell. This - is calculated using the "titrator" function and corresponds to - (1 - v/V) where v is the injection volume and V is the cell volume - dh_param_start_idx : int - index of first enthalpy parameter in guesses array - dh_param_end_idx : int - index of last enthalpy parameter in guesses array - """ - - super().__init__(idx=idx, - expt_idx=expt_idx, - obs_key=obs_key, - micro_array=micro_array, - macro_array=macro_array) - - self._meas_vol_dilution = meas_vol_dilution - self._dh_param_start_idx = dh_param_start_idx - self._dh_param_end_idx = dh_param_end_idx - - - def calc_value(self,parameters,*args,**kwargs): - """ - Calculate the heat for this shot given the current estimated - concentration changes and enthalpy parameters. *args and **kwargs are - ignored. - - Parameters - ---------- - parameters : np.ndarray (float) - fit parameters (guesses array) - """ - - dh_array = parameters[self._dh_param_start_idx:self._dh_param_end_idx] - dC = self._micro_array[self._idx,:] - self._micro_array[self._idx-1,:]*self._meas_vol_dilution - - return np.sum(dC*dh_array) \ No newline at end of file diff --git a/src/linkage/experiment/point/__init__.py b/src/linkage/experiment/point/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/linkage/experiment/point/__init__.py @@ -0,0 +1 @@ + diff --git a/src/linkage/experiment/point/experimental_point.py b/src/linkage/experiment/point/experimental_point.py new file mode 100644 index 0000000..3185323 --- /dev/null +++ b/src/linkage/experiment/point/experimental_point.py @@ -0,0 +1,45 @@ +import numpy as np + +class ExperimentalPoint: + """ + Class for storing an individual experimental data point. Should be sub- + classed. + """ + + def __init__(self, + idx, + expt_idx, + obs_key, + micro_array, + macro_array): + """ + Should be sub-classed. + """ + + self._idx = idx + self._expt_idx = expt_idx + self._obs_key = obs_key + self._micro_array = micro_array + self._macro_array = macro_array + + @property + def idx(self): + """ + Index of point in experimental array. + """ + return self._idx + + @property + def expt_idx(self): + """ + Index of experiment. + """ + return self._expt_idx + + @property + def obs_key(self): + """ + Name of observable. + """ + return self._obs_key + diff --git a/src/linkage/experiment/point/itc_point.py b/src/linkage/experiment/point/itc_point.py new file mode 100644 index 0000000..abee326 --- /dev/null +++ b/src/linkage/experiment/point/itc_point.py @@ -0,0 +1,93 @@ + +from .experimental_point import ExperimentalPoint + +import numpy as np + +class ITCPoint(ExperimentalPoint): + """ + Class holds experimental data for an individual ITC experimental data point + and how it links to the thermodynamic model. + """ + + def __init__(self, + idx, + expt_idx, + obs_key, + micro_array, + macro_array, + meas_vol_dilution, + dh_param_start_idx, + dh_param_end_idx, + dh_sign, + dh_product_mask): + """ + Initialize an ITC data point. + + Parameters + ---------- + idx : int + index of point in the experimental array + expt_idx : int + index of the experiment itself (allowing multiple experiments) + obs_key : str + key pointing to observable from the experiment + micro_array : np.ndarray (float) + array holding concentrations of all microscopic species, calculated + elsewhere + macro_array : np.ndarray (float) + array holding concentrations of all macroscopic species, calculated + elsewhere + meas_vol_dilution : float + how much this shot diluted the measurement volume of the cell. This + is calculated using the "titrator" function and corresponds to + (1 - v/V) where v is the injection volume and V is the cell volume + dh_param_start_idx : int + index of first enthalpy parameter in guesses array + dh_param_end_idx : int + index of last enthalpy parameter in guesses array + dh_sign : list-like + list of enthalpy signs (1 for forward, -1 for reverse) for each + reaction + dh_product_mask : list-like + list of boolean masks for pulling out products when calcuating + enthalpy changes + """ + + super().__init__(idx=idx, + expt_idx=expt_idx, + obs_key=obs_key, + micro_array=micro_array, + macro_array=macro_array) + + self._meas_vol_dilution = meas_vol_dilution + self._dh_param_start_idx = dh_param_start_idx + self._dh_param_end_idx = dh_param_end_idx + self._dh_sign = dh_sign + self._dh_product_mask = dh_product_mask + + + def calc_value(self,parameters,*args,**kwargs): + """ + Calculate the heat for this shot given the current estimated + concentration changes and enthalpy parameters. *args and **kwargs are + ignored. + + Parameters + ---------- + parameters : np.ndarray (float) + fit parameters (guesses array) + """ + + dh_array = parameters[self._dh_param_start_idx:self._dh_param_end_idx] + + total_heat = 0.0 + for i in range(len(dh_array)): + + C_after = self._micro_array[self._idx,self._dh_product_mask[i]] + C_before = self._micro_array[self._idx-1,self._dh_product_mask[i]] + dC = np.mean(C_after - C_before*self._meas_vol_dilution) + + total_heat += dh_array[i]*self._dh_sign[i]*dC + + + return total_heat \ No newline at end of file diff --git a/src/linkage/experiment/point/spec_point.py b/src/linkage/experiment/point/spec_point.py new file mode 100644 index 0000000..6a35990 --- /dev/null +++ b/src/linkage/experiment/point/spec_point.py @@ -0,0 +1,65 @@ + +from .experimental_point import ExperimentalPoint + +import numpy as np + +class SpecPoint(ExperimentalPoint): + """ + Class holds experimental data for an individual spectroscopic + experimental data point and how it links to the binding model. + """ + + def __init__(self, + idx, + expt_idx, + obs_key, + micro_array, + macro_array, + obs_mask, + denom): + """ + Initialize a spectroscopic data point. + + Parameters + ---------- + idx : int + index of point in the experimental array + expt_idx : int + index of the experiment itself (allowing multiple experiments) + obs_key : str + key pointing to observable from the experiment + micro_array : np.ndarray (float) + array holding concentrations of all microscopic species, calculated + elsewhere + macro_array : np.ndarray (float) + array holding concentrations of all macroscopic species, calculated + elsewhere + obs_mask : np.ndarray (bool or int) + mask that grabs microscopic species from micro_array that correspond + to the numerator when calculating the observable + denom : int + index of the macro species that should be used as the denominator + for the observable calculation + """ + + super().__init__(idx=idx, + expt_idx=expt_idx, + obs_key=obs_key, + micro_array=micro_array, + macro_array=macro_array) + + self._obs_mask = obs_mask + self._denom = denom + + def calc_value(self,*args,**kwargs): + """ + Calculate the observable given the estimated concentrations of all + species. *args and **kwargs are ignored. + """ + + num = np.sum(self._micro_array[self._idx,self._obs_mask]) + den = self._macro_array[self._idx,self._denom] + + return num/den + + diff --git a/src/linkage/organizer/global_model.py b/src/linkage/organizer/global_model.py index c7f5989..d5816e4 100644 --- a/src/linkage/organizer/global_model.py +++ b/src/linkage/organizer/global_model.py @@ -1,6 +1,6 @@ import linkage.models -from linkage.experiment.experimental_point import SpecPoint -from linkage.experiment.experimental_point import ITCPoint +from linkage.experiment.point.spec_point import SpecPoint +from linkage.experiment.point.itc_point import ITCPoint import numpy as np import pandas as pd @@ -30,6 +30,9 @@ def __init__(self,expt_list,model_name="SixStateEDTA"): self._bm_param_end_idx = None self._dh_param_start_idx = None self._dh_param_end_idx = None + + self._dh_sign = None + self._dh_product_mask = None # list of all parameter names in the same order as guesses self._all_parameter_names = [] @@ -76,6 +79,7 @@ def _load_model(self): self._all_parameter_names.append(p) self._parameter_guesses.append(0.0) + # Last binding model parameter index is last value self._bm_param_end_idx = len(self._all_parameter_names) - 1 @@ -122,9 +126,26 @@ def _get_enthalpy_param(self): # Index of first enthalpy self._dh_param_start_idx = len(self._all_parameter_names) + self._dh_sign = [] + self._dh_product_mask = [] + for k in self._bm.equilibria: + + reactants = self._bm.equilibria[k][0] + products =self._bm.equilibria[k][1] + + if len(products) <= len(reactants): + self._dh_sign.append(1.0) + key_species = products[:] + else: + self._dh_sign.append(-1.0) + key_species = reactants[:] + + self._dh_product_mask.append(np.isin(self._bm.micro_species, + key_species)) + # Names for all enthalpies - for s in self._bm.micro_species: - self._all_parameter_names.append(f"dH_{s}") + for s in self._bm.param_names: + self._all_parameter_names.append(f"dH_{s[1:]}") self._parameter_guesses.append(0.0) # Last enthalpy index is last entry @@ -209,7 +230,9 @@ def _build_point_map(self): macro_array=self._macro_arrays[-1], meas_vol_dilution=meas_vol_dilution, dh_param_start_idx=self._dh_param_start_idx, - dh_param_end_idx=self._dh_param_end_idx + 1) + dh_param_end_idx=self._dh_param_end_idx + 1, + dh_sign=self._dh_sign, + dh_product_mask=self._dh_product_mask) else: obs_type = obs_info["obs_type"] diff --git a/tests/linkage/experiment/point/test_experimental_point.py b/tests/linkage/experiment/point/test_experimental_point.py new file mode 100644 index 0000000..595baf1 --- /dev/null +++ b/tests/linkage/experiment/point/test_experimental_point.py @@ -0,0 +1,26 @@ + +from linkage.experiment.point.experimental_point import ExperimentalPoint + +import numpy as np + +def test_ExperimentalPoint(): + + # Test properties and basic setter/getter + idx = 0 + expt_idx = 1 + obs_key = "test" + micro_array = np.ones(10) + macro_array = np.ones(3) + e = ExperimentalPoint(idx=idx, + expt_idx=expt_idx, + obs_key=obs_key, + micro_array=micro_array, + macro_array=macro_array) + + assert e.idx == 0 + assert e.expt_idx == 1 + assert e.obs_key == "test" + + assert e._micro_array is micro_array + assert e._macro_array is macro_array + diff --git a/tests/linkage/experiment/point/test_itc_point.py b/tests/linkage/experiment/point/test_itc_point.py new file mode 100644 index 0000000..3cbd9c3 --- /dev/null +++ b/tests/linkage/experiment/point/test_itc_point.py @@ -0,0 +1,123 @@ + +from linkage.experiment.point.itc_point import ITCPoint + +import numpy as np + +def test_ITCPoint(): + + # First, test __init__ and setter/getters + + idx = 0 + expt_idx = 1 + obs_key = "test" + micro_array = np.ones((50,10),dtype=float) + macro_array = np.ones((50,3),dtype=float) + meas_vol_dilution = 1.0 + dh_param_start_idx = 1 + dh_param_end_idx = 3 + dh_sign = np.array([1,-1]) + m0 = np.zeros(10,dtype=bool) + m1 = np.zeros(10,dtype=bool) + m0[0] = True + m1[1] = True + dh_product_mask = [m0,m1] + + e = ITCPoint(idx=idx, + expt_idx=expt_idx, + obs_key=obs_key, + micro_array=micro_array, + macro_array=macro_array, + meas_vol_dilution=meas_vol_dilution, + dh_param_start_idx=dh_param_start_idx, + dh_param_end_idx=dh_param_end_idx, + dh_sign=dh_sign, + dh_product_mask=dh_product_mask) + + assert e.idx == 0 + assert e.expt_idx == 1 + assert e.obs_key == "test" + assert e._micro_array is micro_array + assert e._macro_array is macro_array + + assert e._meas_vol_dilution == meas_vol_dilution + assert e._dh_param_start_idx == dh_param_start_idx + assert e._dh_param_end_idx == dh_param_end_idx + assert e._dh_sign is dh_sign + assert e._dh_product_mask is dh_product_mask + + # Now test calculator. Silly test given everyone is zero, but make sure + # it runs. + parameters = np.zeros(5) + parameters[1] = 1 + parameters[2] = 4 + + calc_value = e.calc_value(parameters=parameters) + assert calc_value == 0 + +def test_ITCPoints_get_value(): + + # first stop (for ITC experiment) + idx = 1 + + # ignored in this test + expt_idx = 0 + obs_key = "ignored" + macro_array = np.zeros((2,3),dtype=float) + + # Make a micro array that has two rows and five microspecies + micro_array = np.zeros((2,5),dtype=float) + + # Species 1 changes from 1.0 -> 1.2 over this step + micro_array[0,1] = 1.0 + micro_array[1,1] = 1.2 + + # Species 2 changes from 1.0 -> 0.8 over this step + micro_array[0,2] = 1.0 + micro_array[1,2] = 0.8 + + # dilution + meas_vol_dilution = (1 - 2/280) + + # Parameters in array are 3 and 4 + dh_param_start_idx = 3 + dh_param_end_idx = 5 + + # negative and positive sign for dH + dh_sign = [-1,1] + + # Look at species 1 and 2 + dh_product_mask = [np.array([False,True,False,False,False],dtype=bool), + np.array([False,False,True,False,False],dtype=bool)] + + + # dH first is 1, dH second is 10 + parameters = np.zeros(10) + parameters[3] = 1 + parameters[4] = 10 + + e = ITCPoint(idx=idx, + expt_idx=expt_idx, + obs_key=obs_key, + micro_array=micro_array, + macro_array=macro_array, + meas_vol_dilution=meas_vol_dilution, + dh_param_start_idx=dh_param_start_idx, + dh_param_end_idx=dh_param_end_idx, + dh_sign=dh_sign, + dh_product_mask=dh_product_mask) + + calculated_value = e.calc_value(parameters=parameters) + + # Manually calculate what we expect this to do + rxn0 = (micro_array[1,1] - micro_array[0,1]*meas_vol_dilution)*dh_sign[0]*parameters[3] + rxn1 = (micro_array[1,2] - micro_array[0,2]*meas_vol_dilution)*dh_sign[1]*parameters[4] + expected_value = rxn0 + rxn1 + + assert np.isclose(calculated_value,expected_value) + + + + + + + diff --git a/tests/linkage/experiment/point/test_spec_point.py b/tests/linkage/experiment/point/test_spec_point.py new file mode 100644 index 0000000..a91647a --- /dev/null +++ b/tests/linkage/experiment/point/test_spec_point.py @@ -0,0 +1,111 @@ + +from linkage.experiment.point.spec_point import SpecPoint + +import numpy as np + +def test_SpecPoint(): + + # Test properties and basic setter/getter + idx = 0 + expt_idx = 1 + obs_key = "test" + micro_array = np.ones((50,10),dtype=float) + macro_array = np.ones((50,3),dtype=float) + + obs_mask = np.zeros(10,dtype=bool) + obs_mask[1] = True + denom = 2 + + e = SpecPoint(idx=idx, + expt_idx=expt_idx, + obs_key=obs_key, + micro_array=micro_array, + macro_array=macro_array, + obs_mask=obs_mask, + denom=denom) + + assert e.idx == 0 + assert e.expt_idx == 1 + assert e.obs_key == "test" + + assert e._micro_array is micro_array + assert e._macro_array is macro_array + + assert e._obs_mask is obs_mask + assert e._denom == denom + +def test_SpecPoint_calc_value(): + + + idx = 0 + expt_idx = 1 + obs_key = "test" + + micro_array = np.ones((50,10),dtype=float) + macro_array = np.ones((50,3),dtype=float) + + # Point 0 and 1 in micro array + micro_array[0,1] = 50 + micro_array[1,1] = 100 + + # Point 0 and 1 in macro array + macro_array[0,2] = 50 + macro_array[1,2] = 150 + + # look at species 1 in micro array + obs_mask = np.zeros(10,dtype=bool) + obs_mask[1] = True + + # Look at species 2 in macro array + denom = 2 + + e = SpecPoint(idx=0, + expt_idx=expt_idx, + obs_key=obs_key, + micro_array=micro_array, + macro_array=macro_array, + obs_mask=obs_mask, + denom=denom) + + assert e.calc_value() == 50/50 + + + e = SpecPoint(idx=1, + expt_idx=expt_idx, + obs_key=obs_key, + micro_array=micro_array, + macro_array=macro_array, + obs_mask=obs_mask, + denom=denom) + + assert e.calc_value() == 100/150 + + + # Now look at points 1 and 2 + micro_array[0,2] = 50 + micro_array[1,2] = 50 + + obs_mask = np.zeros(10,dtype=bool) + obs_mask[1] = True + obs_mask[2] = True + + e = SpecPoint(idx=0, + expt_idx=expt_idx, + obs_key=obs_key, + micro_array=micro_array, + macro_array=macro_array, + obs_mask=obs_mask, + denom=denom) + + assert e.calc_value() == (50 + 50)/50 + + + e = SpecPoint(idx=1, + expt_idx=expt_idx, + obs_key=obs_key, + micro_array=micro_array, + macro_array=macro_array, + obs_mask=obs_mask, + denom=denom) + + assert e.calc_value() == (100 + 50)/150 \ No newline at end of file diff --git a/tests/linkage/organizer/test_global_model.py b/tests/linkage/organizer/test_global_model.py index 19aed36..1cc22e9 100644 --- a/tests/linkage/organizer/test_global_model.py +++ b/tests/linkage/organizer/test_global_model.py @@ -4,8 +4,8 @@ import linkage from linkage.organizer.global_model import GlobalModel -from linkage.experiment.experimental_point import SpecPoint -from linkage.experiment.experimental_point import ITCPoint +from linkage.experiment.point.spec_point import SpecPoint +from linkage.experiment.point.itc_point import ITCPoint import numpy as np import pandas as pd @@ -109,11 +109,21 @@ def test_GlobalModel__get_enthalpy_param(fake_spec_and_itc_data): assert gf._dh_param_start_idx is not None assert gf._dh_param_end_idx is not None - expected = ['dH_I','dH_A','dH_C','dH_E', - 'dH_AC1','dH_AC2','dH_AC3','dH_AC4','dH_EC'] + expected = ['dH_I','dH_E','dH_1','dH_2','dH_3','dH_4'] dh_param = gf._all_parameter_names[gf._dh_param_start_idx:gf._dh_param_end_idx + 1] - assert np.array_equal(expected,dh_param) + + # "EC","I","AC1","AC2","AC3","AC4" + order_in_class = np.array([8,0,4,5,6,7]) + + # make sure it is correctly mapping reactions + assert gf._dh_param_start_idx == 6 + assert gf._dh_param_end_idx == 11 + assert np.array_equal(gf._dh_sign,np.ones(6,dtype=float)) + for i in range(6): + assert np.sum(gf._dh_product_mask[i]) == 1 + assert np.arange(9,dtype=int)[gf._dh_product_mask[i]] == order_in_class[i] + # Remove itc experiment; should have no enthalpies this_expt_list = copy.deepcopy(base_expt_list) @@ -122,6 +132,8 @@ def test_GlobalModel__get_enthalpy_param(fake_spec_and_itc_data): expt_list=this_expt_list) assert gf._dh_param_start_idx is None assert gf._dh_param_end_idx is None + assert gf._dh_sign is None + assert gf._dh_product_mask is None def test_GlobalModel__process_expt_fudge(fake_spec_and_itc_data): From 0822734f12855c3a6a05418680dc61ba3aaac514 Mon Sep 17 00:00:00 2001 From: Michael Harms Date: Mon, 29 Jul 2024 15:51:43 -0700 Subject: [PATCH 09/17] cleaned up and added tests to experiment --- src/linkage/experiment/__init__.py | 1 + src/linkage/experiment/experiment.py | 105 +++++-- src/linkage/experiment/titrator.py | 169 ++++++---- src/linkage/organizer/global_model.py | 5 +- tests/linkage/experiment/test_experiment.py | 322 ++++++++++++++++++++ tests/linkage/experiment/test_titrator.py | 124 ++++++++ 6 files changed, 639 insertions(+), 87 deletions(-) create mode 100644 tests/linkage/experiment/test_experiment.py diff --git a/src/linkage/experiment/__init__.py b/src/linkage/experiment/__init__.py index a625657..7b86bde 100644 --- a/src/linkage/experiment/__init__.py +++ b/src/linkage/experiment/__init__.py @@ -1,2 +1,3 @@ from linkage.experiment.experiment import Experiment + diff --git a/src/linkage/experiment/experiment.py b/src/linkage/experiment/experiment.py index 381c4b8..f7d5053 100644 --- a/src/linkage/experiment/experiment.py +++ b/src/linkage/experiment/experiment.py @@ -1,8 +1,65 @@ from linkage.experiment.titrator import titrator +from linkage.experiment.titrator import sync_cell_and_syringe import numpy as np import pandas as pd +import copy + +def _load_dataframe(expt_data): + + # If this is a string, try to load it as a file + if type(expt_data) is str: + + filename = expt_data + + ext = filename.split(".")[-1].strip().lower() + + if ext in ["xlsx","xls"]: + df = pd.read_excel(filename) + elif ext == "csv": + df = pd.read_csv(filename,sep=",") + elif ext == "tsv": + df = pd.read_csv(filename,sep="\t") + else: + # Fall back -- try to guess delimiter + df = pd.read_csv(filename,sep=None,engine="python") + + # If this is a pandas dataframe, work in a copy of it. + elif type(expt_data) is pd.DataFrame: + df = expt_data.copy() + + # Otherwise, fail + else: + err = f"\n\n'expt_data' {expt_data} not recognized. Should be the\n" + err += "filename of a spreadsheet or a pandas dataframe.\n" + raise ValueError(err) + + return df + + +def _preprocess_df(expt_data): + + if "injection" not in expt_data.columns: + err = "expt_data should be a dataframe or spreadsheet with a 'injection' column\n" + raise ValueError(err) + + if "ignore_point" not in expt_data.columns: + expt_data["ignore_point"] = np.zeros(len(expt_data),dtype=bool) + + + # If there is no "0" injections start -- like in ITC, for example -- add this with + # np.nan for all non-injection values + if not np.isclose(expt_data.loc[expt_data.index[0],"injection"],0): + new_row = dict([(c,[np.nan]) for c in expt_data.columns]) + new_row["injection"] = [0.0] + new_row["ignore_point"] = [True] + new_row = pd.DataFrame(new_row) + expt_data = pd.concat((new_row,expt_data),ignore_index=True) + + return expt_data + + class Experiment: def __init__(self, @@ -13,42 +70,24 @@ def __init__(self, cell_volume=1800, constant_volume=False): - if not issubclass(type(expt_data),pd.DataFrame): - expt_data = pd.read_excel(expt_data) - - self._expt_data = expt_data - if "injection" not in self._expt_data.columns: - err = "expt_data should be a dataframe or spreadsheet with a 'injection' column\n" - raise ValueError(err) - - if "ignore_point" not in self._expt_data.columns: - self._expt_data["ignore_point"] = np.zeros(len(self._expt_data),dtype=bool) - - # If there is no "0" injections start -- like in ITC, for example -- add this with - # np.nan for all non-injection values - if not np.isclose(self._expt_data.loc[self._expt_data.index[0],"injection"],0): - new_row = dict([(c,[np.nan]) for c in self._expt_data.columns]) - new_row["injection"] = [0.0] - new_row["ignore_point"] = [True] - new_row = pd.DataFrame(new_row) - self._expt_data = pd.concat((new_row,self._expt_data),ignore_index=True) - - if not issubclass(type(cell_contents),dict): - err = "cell_contents should be a dictionary with initial cell concs\n" - raise ValueError(err) - - if not issubclass(type(syringe_contents),dict): - err = "syringe_contents should be a dictionary with initial syringe concs\n" - raise ValueError(err) + # Process and clean up input experimental data + expt_data = _load_dataframe(expt_data=expt_data) + self._expt_data = _preprocess_df(expt_data=expt_data) + + # Process and clean up cell and syringe data + _, cell_contents, syringe_contents = sync_cell_and_syringe(cell_contents, + syringe_contents) + self._initial_cell_contents = copy.deepcopy(cell_contents) + self._syringe_contents = copy.deepcopy(syringe_contents) # Calculate the total concentrations over the experiment self._expt_concs = titrator(cell_contents=cell_contents, syringe_contents=syringe_contents, - cell_volume=cell_volume, injection_array=np.array(self._expt_data["injection"]), + cell_volume=cell_volume, constant_volume=constant_volume) - # Make sure conc_to_float is sane + # Make sure conc_to_float is sane. if conc_to_float is not None: if conc_to_float not in self._expt_concs.columns: err = "conc_to_float is not a macrospecies in the experiment\n" @@ -125,3 +164,11 @@ def observables(self): @property def conc_to_float(self): return self._conc_to_float + + @property + def syringe_contents(self): + return self._syringe_contents + + @property + def initial_cell_contents(self): + return self._initial_cell_contents \ No newline at end of file diff --git a/src/linkage/experiment/titrator.py b/src/linkage/experiment/titrator.py index 5179a51..3ddf479 100644 --- a/src/linkage/experiment/titrator.py +++ b/src/linkage/experiment/titrator.py @@ -3,10 +3,106 @@ import copy +def sync_cell_and_syringe(cell_contents, + syringe_contents): + + if not issubclass(type(cell_contents),dict): + err = "cell_contents should be a dictionary with initial cell concs\n" + raise ValueError(err) + + if not issubclass(type(syringe_contents),dict): + err = "syringe_contents should be a dictionary with initial syringe concs\n" + raise ValueError(err) + + # List of all species in syringe and cell + species = list(set(syringe_contents.keys()).union(set(cell_contents.keys()))) + species.sort() + + # Copy syringe and cell dictionaries because we are about to modify + # them. + syringe_contents = copy.deepcopy(syringe_contents) + cell_contents = copy.deepcopy(cell_contents) + + # If a species is only in the syringe or cell, set it to zero in the + # other pool + for s in species: + if s not in syringe_contents: + syringe_contents[s] = 0.0 + if s not in cell_contents: + cell_contents[s] = 0.0 + + return species, cell_contents, syringe_contents + +def _titr_constant_volume(cell_contents, + syringe_contents, + injection_array, + cell_volume, + out): + + # For each injection + for i in range(len(injection_array)): + + # Record current volume and injection + out["injection"].append(injection_array[i]) + out["volume"].append(cell_volume) + out["meas_vol_dilution"].append(1) + + # Update cell concs based on injected titrant + for s in cell_contents.keys(): + + prev_conc = cell_contents[s] + + a = (cell_volume - injection_array[i])*prev_conc + b = injection_array[i]*syringe_contents[s] + + cell_contents[s] = (a + b)/cell_volume + out[s].append(cell_contents[s]) + + return out + +def _titr_increase_volume(cell_contents, + syringe_contents, + injection_array, + cell_volume, + out): + + # For each injection + start_vol = cell_volume + meas_vol_dilution = 1 + for i in range(len(injection_array)): + + # Get starting volume + if len(out["injection"]) > 0: + start_vol = out["volume"][-1] + meas_vol_dilution = (1 - injection_array[i]/cell_volume) + + # Get volume after this injection is injected + new_vol = start_vol + injection_array[i] + + # Record current volume and injection + out["injection"].append(injection_array[i]) + out["volume"].append(new_vol) + out["meas_vol_dilution"].append(meas_vol_dilution) + + # Update cell concs based on injected titrant + for s in cell_contents.keys(): + + prev_conc = cell_contents[s] + + a = start_vol*prev_conc + b = injection_array[i]*syringe_contents[s] + + cell_contents[s] = (a + b)/new_vol + out[s].append(cell_contents[s]) + + return out + + + def titrator(cell_contents, syringe_contents, + injection_array, cell_volume=1800, - injection_array=None, constant_volume=False): """ Simulate a titrator injecting constant volumes into a cell. Calculate the @@ -39,23 +135,9 @@ def titrator(cell_contents, pandas dataframe with the concentrations of all species in the cell versus injections in the experiment """ - - # List of all species in syringe and cell - species = list(set(syringe_contents.keys()).union(set(cell_contents.keys()))) - species.sort() - - # Copy syringe and cell dictionaries because we are about to modify - # them. - syringe_contents = copy.deepcopy(syringe_contents) - cell_contents = copy.deepcopy(cell_contents) - - # If a species is only in the syringe or cell, set it to zero in the - # other pool - for s in species: - if s not in syringe_contents: - syringe_contents[s] = 0.0 - if s not in cell_contents: - cell_contents[s] = 0.0 + + species, cell_contents, syringe_contents = sync_cell_and_syringe(cell_contents, + syringe_contents) # Ensure injection_array is a numpy array of floats injection_array = np.array(injection_array,dtype=float) @@ -67,45 +149,20 @@ def titrator(cell_contents, out["meas_vol_dilution"] = [] for s in species: out[s] = [] - - # For each injection - for i in range(len(injection_array)): - - # Get starting volume - if len(out["injection"]) == 0: - start_vol = cell_volume - else: - start_vol = out["volume"][-1] - - # Get volume after this injection is injected - if constant_volume: - new_vol = start_vol - else: - new_vol = start_vol + injection_array[i] - - if len(out["injection"]) == 0: - meas_vol_dilution = 1 - else: - meas_vol_dilution = (1 - injection_array[i]/cell_volume) - - # Record current volume and injection - out["injection"].append(injection_array[i]) - out["volume"].append(new_vol) - out["meas_vol_dilution"].append(meas_vol_dilution) - - # Update cell concs based on injected titrant - for s in species: - - prev_conc = cell_contents[s] - - if constant_volume: - a = (cell_volume - injection_array[i])*prev_conc - else: - a = start_vol*prev_conc + - b = injection_array[i]*syringe_contents[s] - cell_contents[s] = (a + b)/new_vol - out[s].append(cell_contents[s]) + if constant_volume: + out = _titr_constant_volume(cell_contents, + syringe_contents, + injection_array, + cell_volume, + out) + else: + out = _titr_increase_volume(cell_contents, + syringe_contents, + injection_array, + cell_volume, + out) # Convert out to dataframe and return return pd.DataFrame(out) diff --git a/src/linkage/organizer/global_model.py b/src/linkage/organizer/global_model.py index d5816e4..f48841a 100644 --- a/src/linkage/organizer/global_model.py +++ b/src/linkage/organizer/global_model.py @@ -9,7 +9,9 @@ class GlobalModel: - def __init__(self,expt_list,model_name="SixStateEDTA"): + def __init__(self, + expt_list, + model_name="SixStateEDTA"): """ Initialize a global fit. @@ -79,7 +81,6 @@ def _load_model(self): self._all_parameter_names.append(p) self._parameter_guesses.append(0.0) - # Last binding model parameter index is last value self._bm_param_end_idx = len(self._all_parameter_names) - 1 diff --git a/tests/linkage/experiment/test_experiment.py b/tests/linkage/experiment/test_experiment.py new file mode 100644 index 0000000..8cd766f --- /dev/null +++ b/tests/linkage/experiment/test_experiment.py @@ -0,0 +1,322 @@ +import pytest + +from linkage.experiment.experiment import _load_dataframe +from linkage.experiment.experiment import _preprocess_df +from linkage.experiment.experiment import Experiment + +import pandas as pd +import numpy as np + +import os +import shutil + +def test__load_dataframe(tmp_path): + + cwd = os.getcwd() + os.chdir(tmp_path) + + out = {"test":[1,2,3]} + df = pd.DataFrame(out) + + out_df = _load_dataframe(df) + assert not out_df is df # return copy + assert len(out_df) == 3 + assert np.allclose(out_df["test"],[1,2,3]) + + df.to_csv("junk.csv") + out_df = _load_dataframe("junk.csv") + assert not out_df is df + assert len(out_df) == 3 + assert np.allclose(out_df["test"],[1,2,3]) + + df.to_csv("junk.tsv",sep="\t") + out_df = _load_dataframe("junk.tsv") + assert not out_df is df + assert len(out_df) == 3 + assert np.allclose(out_df["test"],[1,2,3]) + + df.to_csv("junk.txt") + out_df = _load_dataframe("junk.txt") + assert not out_df is df + assert len(out_df) == 3 + assert np.allclose(out_df["test"],[1,2,3]) + + df.to_excel("junk.xlsx") + out_df = _load_dataframe("junk.xlsx") + assert not out_df is df + assert len(out_df) == 3 + assert np.allclose(out_df["test"],[1,2,3]) + + shutil.copy("junk.xlsx","junk.xls") + out_df = _load_dataframe("junk.xls") + assert not out_df is df + assert len(out_df) == 3 + assert np.allclose(out_df["test"],[1,2,3]) + + with pytest.raises(FileNotFoundError): + out_df = _load_dataframe("junk_not_real.xslx") + + with pytest.raises(ValueError): + out_df = _load_dataframe(1.0) + + + os.chdir(cwd) + + +def test__preprocess_df(): + + df = pd.DataFrame({"injection":[1,2,3]}) + out_df = _preprocess_df(df) + assert np.array_equal(out_df.columns,["injection","ignore_point"]) + + df = pd.DataFrame({"out":[1,2,3]}) + with pytest.raises(ValueError): + out_df = _preprocess_df(df) + + df = pd.DataFrame({"injection":[1,2], + "ignore_point":[False,False]}) + out_df = _preprocess_df(df) + assert len(out_df) == 3 + assert np.array_equal(out_df.columns,["injection","ignore_point"]) + assert np.array_equal(out_df["injection"],[0,1,2]) + assert np.array_equal(out_df["ignore_point"],[True,False,False]) + + + df = pd.DataFrame({"injection":[1,2], + "ignore_point":[False,False], + "obs":[1,1]}) + out_df = _preprocess_df(df) + assert len(out_df) == 3 + assert np.array_equal(out_df.columns,["injection","ignore_point","obs"]) + assert np.array_equal(out_df["injection"],[0,1,2]) + assert np.array_equal(out_df["ignore_point"],[True,False,False]) + assert np.array_equal(out_df["obs"],[np.nan,1,1],equal_nan=True) + + +def test_Experiment(): + + expt_data = pd.DataFrame({"injection":[0,1,1]}) + cell_contents = {"A":10} + syringe_contents = {"B":10} + conc_to_float = None + cell_volume = 100 + constant_volume = False + + e = Experiment(expt_data=expt_data, + cell_contents=cell_contents, + syringe_contents=syringe_contents, + conc_to_float=conc_to_float, + cell_volume=cell_volume, + constant_volume=constant_volume) + + assert issubclass(type(e._expt_data),pd.DataFrame) + assert e._initial_cell_contents["A"] == 10 + assert e._initial_cell_contents["B"] == 0 + assert e._syringe_contents["A"] == 0 + assert e._syringe_contents["B"] == 10 + assert issubclass(type(e._expt_concs),pd.DataFrame) + assert np.array_equal(e._expt_concs.columns,["injection","volume","meas_vol_dilution","A","B"]) + assert e._conc_to_float is None + assert issubclass(type(e._observables),dict) + assert len(e._observables) == 0 + + # check properties + assert e.expt_data is e._expt_data + assert e.expt_concs is e._expt_concs + assert e.observables is e._observables + assert e.conc_to_float is e._conc_to_float + assert e.syringe_contents is e._syringe_contents + assert e.initial_cell_contents is e._initial_cell_contents + + assert np.array_equal(e._expt_concs["volume"],[100,101,102]) + + e = Experiment(expt_data=expt_data, + cell_contents=cell_contents, + syringe_contents=syringe_contents, + conc_to_float="A", + cell_volume=cell_volume, + constant_volume=True) + + assert e._conc_to_float == "A" + assert np.array_equal(e._expt_concs["volume"],[100,100,100]) + + with pytest.raises(ValueError): + e = Experiment(expt_data=expt_data, + cell_contents=cell_contents, + syringe_contents=syringe_contents, + conc_to_float="NOT_THERE", + cell_volume=cell_volume, + constant_volume=True) + +def test_Experiment_add_observable(): + + expt_data = pd.DataFrame({"injection":[0,1,1], + "obs":[1,2,3]}) + cell_contents = {"A":10} + syringe_contents = {"B":10} + conc_to_float = None + cell_volume = 100 + constant_volume = False + + e = Experiment(expt_data=expt_data, + cell_contents=cell_contents, + syringe_contents=syringe_contents, + conc_to_float=conc_to_float, + cell_volume=cell_volume, + constant_volume=constant_volume) + + e.add_observable(column_name="obs", + obs_type="spec", + observable_species=["anything"], + denominator="A") + assert e._observables["obs"]["obs_type"] == "spec" + assert np.array_equal(e._observables["obs"]["observable_species"],["anything"]) + assert e._observables["obs"]["denominator"] == "A" + + # Bad observable column + e = Experiment(expt_data=expt_data, + cell_contents=cell_contents, + syringe_contents=syringe_contents, + conc_to_float=conc_to_float, + cell_volume=cell_volume, + constant_volume=constant_volume) + + with pytest.raises(ValueError): + e.add_observable(column_name="not_a_column", + obs_type="spec", + observable_species=["anything"], + denominator="A") + + # Bad denominator + e = Experiment(expt_data=expt_data, + cell_contents=cell_contents, + syringe_contents=syringe_contents, + conc_to_float=conc_to_float, + cell_volume=cell_volume, + constant_volume=constant_volume) + + with pytest.raises(ValueError): + e.add_observable(column_name="obs", + obs_type="spec", + observable_species=["anything"], + denominator="not_a_species") + + # No observable species + e = Experiment(expt_data=expt_data, + cell_contents=cell_contents, + syringe_contents=syringe_contents, + conc_to_float=conc_to_float, + cell_volume=cell_volume, + constant_volume=constant_volume) + + with pytest.raises(ValueError): + e.add_observable(column_name="obs", + obs_type="spec", + observable_species=None, + denominator="A") + + # Bad observable species + e = Experiment(expt_data=expt_data, + cell_contents=cell_contents, + syringe_contents=syringe_contents, + conc_to_float=conc_to_float, + cell_volume=cell_volume, + constant_volume=constant_volume) + + with pytest.raises(ValueError): + e.add_observable(column_name="obs", + obs_type="spec", + observable_species=1, + denominator="A") + + + # Observable species as list + e = Experiment(expt_data=expt_data, + cell_contents=cell_contents, + syringe_contents=syringe_contents, + conc_to_float=conc_to_float, + cell_volume=cell_volume, + constant_volume=constant_volume) + + e.add_observable(column_name="obs", + obs_type="spec", + observable_species="anything", + denominator="A") + assert e._observables["obs"]["obs_type"] == "spec" + assert np.array_equal(e._observables["obs"]["observable_species"],["anything"]) + assert e._observables["obs"]["denominator"] == "A" + + + # Disallowed column name + e = Experiment(expt_data=expt_data, + cell_contents=cell_contents, + syringe_contents=syringe_contents, + conc_to_float=conc_to_float, + cell_volume=cell_volume, + constant_volume=constant_volume) + + with pytest.raises(ValueError): + e.add_observable(column_name="injection", + obs_type="spec", + observable_species=["anything"], + denominator="A") + + + # Send in ITC experiment + e = Experiment(expt_data=expt_data, + cell_contents=cell_contents, + syringe_contents=syringe_contents, + conc_to_float=conc_to_float, + cell_volume=cell_volume, + constant_volume=constant_volume) + + e.add_observable(column_name="obs", + obs_type="itc", + observable_species=None, + denominator=None) + assert e._observables["obs"]["obs_type"] == "itc" + assert e._observables["obs"]["observable_species"] is None + assert e._observables["obs"]["denominator"] is None + + # Observable not recognized + e = Experiment(expt_data=expt_data, + cell_contents=cell_contents, + syringe_contents=syringe_contents, + conc_to_float=conc_to_float, + cell_volume=cell_volume, + constant_volume=constant_volume) + + with pytest.raises(ValueError): + e.add_observable(column_name="obs", + obs_type="not_really_osbervable", + observable_species=["anything"], + denominator="A") + + +def test_add_expt_column(): + + expt_data = pd.DataFrame({"injection":[0,1,1]}) + cell_contents = {"A":10} + syringe_contents = {"B":10} + conc_to_float = None + cell_volume = 100 + constant_volume = False + + e = Experiment(expt_data=expt_data, + cell_contents=cell_contents, + syringe_contents=syringe_contents, + conc_to_float=conc_to_float, + cell_volume=cell_volume, + constant_volume=constant_volume) + + e.add_expt_conc_column(new_column="new_column") + assert np.array_equal(e._expt_concs.columns, + ["injection","volume","meas_vol_dilution","A","B","new_column"]) + assert np.array_equal(e._expt_concs["new_column"],np.zeros(3)) + + e.add_expt_conc_column(new_column="blah",conc_vector=np.array([3,2,1])) + assert np.array_equal(e._expt_concs.columns, + ["injection","volume","meas_vol_dilution","A","B","new_column","blah"]) + assert np.array_equal(e._expt_concs["blah"],[3,2,1]) + + \ No newline at end of file diff --git a/tests/linkage/experiment/test_titrator.py b/tests/linkage/experiment/test_titrator.py index 7ba7f80..b1e5526 100644 --- a/tests/linkage/experiment/test_titrator.py +++ b/tests/linkage/experiment/test_titrator.py @@ -3,6 +3,9 @@ import pandas as pd from linkage.experiment.titrator import titrator +from linkage.experiment.titrator import sync_cell_and_syringe +from linkage.experiment.titrator import _titr_constant_volume +from linkage.experiment.titrator import _titr_increase_volume import copy @@ -17,5 +20,126 @@ def test_titrator(): kwargs = copy.deepcopy(base_kwargs) df = titrator(**kwargs) assert issubclass(type(df),pd.DataFrame) + assert len(df) == 10 + assert np.allclose(np.array(df["volume"]),100 + np.arange(1,11)) + + kwargs = copy.deepcopy(base_kwargs) + kwargs["constant_volume"] = True + df = titrator(**kwargs) + assert issubclass(type(df),pd.DataFrame) + assert len(df) == 10 + assert np.allclose(np.array(df["volume"]),100*np.ones(10)) + + +def test_sync_cell_and_syringe(): + + cell = {"A":1,"B":2} + syringe = {"A":10,"C":20} + + species, cell, syringe = sync_cell_and_syringe(cell_contents=cell, + syringe_contents=syringe) + + assert np.array_equal(species,["A","B","C"]) + + assert cell["A"] == 1 + assert cell["B"] == 2 + assert cell["C"] == 0 + + assert syringe["A"] == 10 + assert syringe["B"] == 0 + assert syringe["C"] == 20 + + with pytest.raises(ValueError): + species, cell, syringe = sync_cell_and_syringe(cell_contents=1, + syringe_contents=syringe) + + with pytest.raises(ValueError): + species, cell, syringe = sync_cell_and_syringe(cell_contents=cell, + syringe_contents=-1) + + +def test__titr_constant_volume(): + + cell = {"A":1,"B":2,"C":0} + syringe = {"A":10,"B":0,"C":20} + injection_array = np.ones(3,dtype=float) + injection_array[0] = 0.0 + injection_array[2] = 10 + cell_volume = 100 + + out = {} + out["injection"] = [] + out["volume"] = [] + out["meas_vol_dilution"] = [] + out["A"] = [] + out["B"] = [] + out["C"] = [] + + out = _titr_constant_volume(cell_contents=cell, + syringe_contents=syringe, + injection_array=injection_array, + cell_volume=cell_volume, + out=out) + + + assert np.array_equal(out["injection"],injection_array) + assert np.array_equal(out["volume"],[100,100,100]) + assert np.array_equal(out["meas_vol_dilution"],[1,1,1]) + assert np.allclose(out["A"], + [1, + ((100 - 1)*1 + 10*1)/100, + ((100 - 10)*1.09 + 10*10)/100]) + assert np.allclose(out["B"], + [2, + ((100 - 1)*2)/100, + ((100 - 10)*1.98)/100]) + assert np.allclose(out["C"], + [0, + 20/100, + ((100 - 10)*20/100 + 20*10)/100]) + + +def test__titr_increase_volume(): + + cell = {"A":1,"B":2,"C":0} + syringe = {"A":10,"B":0,"C":20} + injection_array = np.ones(3,dtype=float) + injection_array[0] = 0.0 + injection_array[2] = 10 + cell_volume = 100 + + out = {} + out["injection"] = [] + out["volume"] = [] + out["meas_vol_dilution"] = [] + out["A"] = [] + out["B"] = [] + out["C"] = [] + + out = _titr_increase_volume(cell_contents=cell, + syringe_contents=syringe, + injection_array=injection_array, + cell_volume=cell_volume, + out=out) + + assert np.array_equal(out["injection"],injection_array) + assert np.array_equal(out["volume"],[100,101,111]) + assert np.array_equal(out["meas_vol_dilution"],[1,1-1/100,1-10/100]) + + + assert np.allclose(out["A"], + [1, + (100*1 + 1*10)/101, + ((100*1 + 1*10)/101*101 + 10*10)/111]) + + assert np.allclose(out["B"], + [2, + (100*2)/101, + ((100*2)/101*101)/111]) + + assert np.allclose(out["C"], + [0, + 1*20/101, + (101*1*20/101 + 20*10)/111]) From df283d535dbd3b02ef6956b2cc3446b452bf1c28 Mon Sep 17 00:00:00 2001 From: Michael Harms Date: Mon, 29 Jul 2024 16:53:53 -0700 Subject: [PATCH 10/17] added heat of dilution --- docs/badges/coverage-badge.svg | 2 +- docs/badges/tests-badge.svg | 2 +- reports/flake.txt | 2290 ++++++++++------- reports/junit/junit.xml | 2 +- .../experiment/point/experimental_point.py | 4 +- src/linkage/experiment/point/itc_point.py | 28 +- src/linkage/experiment/point/spec_point.py | 7 +- src/linkage/organizer/global_model.py | 22 +- .../point/test_experimental_point.py | 5 +- .../experiment/point/test_itc_point.py | 10 +- .../experiment/point/test_spec_point.py | 9 +- tests/linkage/organizer/test_global_model.py | 4 +- 12 files changed, 1443 insertions(+), 942 deletions(-) diff --git a/docs/badges/coverage-badge.svg b/docs/badges/coverage-badge.svg index 2ce7beb..d6e7b66 100644 --- a/docs/badges/coverage-badge.svg +++ b/docs/badges/coverage-badge.svg @@ -1 +1 @@ -coverage: 91.90%coverage91.90% \ No newline at end of file +coverage: 95.45%coverage95.45% \ No newline at end of file diff --git a/docs/badges/tests-badge.svg b/docs/badges/tests-badge.svg index 56180de..aefefb0 100644 --- a/docs/badges/tests-badge.svg +++ b/docs/badges/tests-badge.svg @@ -1 +1 @@ -tests: 16tests16 \ No newline at end of file +tests: 30tests30 \ No newline at end of file diff --git a/reports/flake.txt b/reports/flake.txt index 059e062..4acabfa 100644 --- a/reports/flake.txt +++ b/reports/flake.txt @@ -10,6 +10,7 @@ ./build/lib/linkage/cli.py:20:1: W293 blank line contains whitespace ./build/lib/linkage/cli.py:20:5: W292 no newline at end of file ./build/lib/linkage/experiment/__init__.py:2:1: F401 'linkage.experiment.experiment.Experiment' imported but unused +./build/lib/linkage/experiment/__init__.py:3:1: W391 blank line at end of file ./build/lib/linkage/experiment/baseline_corrector.py:4:1: E302 expected 2 blank lines, found 1 ./build/lib/linkage/experiment/baseline_corrector.py:4:25: E231 missing whitespace after ',' ./build/lib/linkage/experiment/baseline_corrector.py:4:27: E231 missing whitespace after ',' @@ -31,31 +32,38 @@ ./build/lib/linkage/experiment/baseline_corrector.py:43:18: E231 missing whitespace after ',' ./build/lib/linkage/experiment/baseline_corrector.py:43:45: E231 missing whitespace after ',' ./build/lib/linkage/experiment/baseline_corrector.py:43:49: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:6:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/experiment/experiment.py:16:42: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:25:76: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:27:91: W291 trailing whitespace -./build/lib/linkage/experiment/experiment.py:29:71: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:29:84: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:30:31: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:34:49: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:34:66: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:35:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experiment.py:36:46: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:40:49: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:59:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experiment.py:74:35: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:79:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experiment.py:84:51: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:87:46: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:90:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experiment.py:101:53: E231 missing whitespace after ':' -./build/lib/linkage/experiment/experiment.py:102:63: E231 missing whitespace after ':' -./build/lib/linkage/experiment/experiment.py:103:56: E231 missing whitespace after ':' -./build/lib/linkage/experiment/experiment.py:104:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experiment.py:105:34: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:105:45: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:116:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:9:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/experiment/experiment.py:18:26: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:21:38: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:23:38: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:26:38: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:26:47: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:37:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:48:60: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:51:5: E303 too many blank lines (2) +./build/lib/linkage/experiment/experiment.py:51:87: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:53:55: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:53:68: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:54:27: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:58:39: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:58:50: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:76:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:90:43: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:98:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:113:35: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:118:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:123:51: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:126:46: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:129:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:140:53: E231 missing whitespace after ':' +./build/lib/linkage/experiment/experiment.py:141:63: E231 missing whitespace after ':' +./build/lib/linkage/experiment/experiment.py:142:56: E231 missing whitespace after ':' +./build/lib/linkage/experiment/experiment.py:143:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:144:34: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:144:45: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:155:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:171:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:174:43: W292 no newline at end of file ./build/lib/linkage/experiment/experimental_point.py:3:1: E302 expected 2 blank lines, found 1 ./build/lib/linkage/experiment/experimental_point.py:6:13: W291 trailing whitespace ./build/lib/linkage/experiment/experimental_point.py:8:1: W293 blank line contains whitespace @@ -90,202 +98,263 @@ ./build/lib/linkage/experiment/experimental_point.py:174:76: E231 missing whitespace after ',' ./build/lib/linkage/experiment/experimental_point.py:175:1: W293 blank line contains whitespace ./build/lib/linkage/experiment/experimental_point.py:176:35: W292 no newline at end of file -./build/lib/linkage/experiment/titrator.py:6:1: C901 'titrator' is too complex (11) +./build/lib/linkage/experiment/point/__init__.py:1:1: W391 blank line at end of file +./build/lib/linkage/experiment/point/experimental_point.py:1:1: F401 'numpy as np' imported but unused +./build/lib/linkage/experiment/point/experimental_point.py:3:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/experiment/point/experimental_point.py:6:13: W291 trailing whitespace +./build/lib/linkage/experiment/point/experimental_point.py:8:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/point/experimental_point.py:19:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/point/experimental_point.py:40:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/point/experimental_point.py:47:1: W391 blank line at end of file +./build/lib/linkage/experiment/point/itc_point.py:6:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/experiment/point/itc_point.py:9:49: W291 trailing whitespace +./build/lib/linkage/experiment/point/itc_point.py:25:38: W291 trailing whitespace +./build/lib/linkage/experiment/point/itc_point.py:26:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/point/itc_point.py:42:78: W291 trailing whitespace +./build/lib/linkage/experiment/point/itc_point.py:46:75: W291 trailing whitespace +./build/lib/linkage/experiment/point/itc_point.py:53:76: W291 trailing whitespace +./build/lib/linkage/experiment/point/itc_point.py:56:75: W291 trailing whitespace +./build/lib/linkage/experiment/point/itc_point.py:59:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/point/itc_point.py:66:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/point/itc_point.py:76:60: W291 trailing whitespace +./build/lib/linkage/experiment/point/itc_point.py:79:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/point/itc_point.py:80:24: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/itc_point.py:80:35: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/itc_point.py:80:41: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/itc_point.py:84:17: W291 trailing whitespace +./build/lib/linkage/experiment/point/itc_point.py:93:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/point/itc_point.py:97:20: E221 multiple spaces before operator +./build/lib/linkage/experiment/point/itc_point.py:97:51: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/itc_point.py:98:53: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/itc_point.py:103:32: W291 trailing whitespace +./build/lib/linkage/experiment/point/itc_point.py:105:71: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/itc_point.py:107:26: W292 no newline at end of file +./build/lib/linkage/experiment/point/spec_point.py:6:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/experiment/point/spec_point.py:8:66: W291 trailing whitespace +./build/lib/linkage/experiment/point/spec_point.py:9:67: W291 trailing whitespace +./build/lib/linkage/experiment/point/spec_point.py:22:47: W291 trailing whitespace +./build/lib/linkage/experiment/point/spec_point.py:23:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/point/spec_point.py:39:78: W291 trailing whitespace +./build/lib/linkage/experiment/point/spec_point.py:55:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/point/spec_point.py:58:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/point/spec_point.py:59:24: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/spec_point.py:59:30: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/spec_point.py:61:75: W291 trailing whitespace +./build/lib/linkage/experiment/point/spec_point.py:65:49: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/spec_point.py:66:42: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/spec_point.py:70:1: W391 blank line at end of file +./build/lib/linkage/experiment/point/test_itc_point.py:6:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/experiment/point/test_itc_point.py:12:30: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/test_itc_point.py:12:34: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/test_itc_point.py:13:30: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/test_itc_point.py:13:33: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/test_itc_point.py:17:26: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/test_itc_point.py:18:21: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/test_itc_point.py:19:21: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/test_itc_point.py:22:26: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/test_itc_point.py:34:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/point/test_itc_point.py:40:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/point/test_itc_point.py:46:1: W391 blank line at end of file ./build/lib/linkage/experiment/titrator.py:6:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/experiment/titrator.py:13:55: W291 trailing whitespace -./build/lib/linkage/experiment/titrator.py:14:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:21:32: W291 trailing whitespace -./build/lib/linkage/experiment/titrator.py:26:32: W291 trailing whitespace -./build/lib/linkage/experiment/titrator.py:31:51: W291 trailing whitespace -./build/lib/linkage/experiment/titrator.py:33:90: W291 trailing whitespace -./build/lib/linkage/experiment/titrator.py:34:67: W291 trailing whitespace -./build/lib/linkage/experiment/titrator.py:35:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:42:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:46:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:51:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:59:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:61:47: E231 missing whitespace after ',' -./build/lib/linkage/experiment/titrator.py:62:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:70:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:100:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:109:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:8:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:9:42: E231 missing whitespace after ',' +./build/lib/linkage/experiment/titrator.py:13:45: E231 missing whitespace after ',' +./build/lib/linkage/experiment/titrator.py:20:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:25:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:36:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/experiment/titrator.py:54:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:63:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/experiment/titrator.py:68:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:81:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:91:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:99:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:102:1: E303 too many blank lines (3) +./build/lib/linkage/experiment/titrator.py:109:55: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:110:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:117:32: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:122:32: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:127:51: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:129:90: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:130:67: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:131:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:141:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:143:47: E231 missing whitespace after ',' +./build/lib/linkage/experiment/titrator.py:144:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:152:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:154:5: E303 too many blank lines (2) +./build/lib/linkage/experiment/titrator.py:166:1: W293 blank line contains whitespace ./build/lib/linkage/models/__init__.py:2:1: F401 'linkage.models.six_state_edta.SixStateEDTA' imported but unused ./build/lib/linkage/models/__init__.py:3:1: F401 'linkage.models.ca_edta.CaEDTA' imported but unused -./build/lib/linkage/models/base.py:6:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/models/base.py:9:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:19:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:28:13: E722 do not use bare 'except' -./build/lib/linkage/models/base.py:31:14: W291 trailing whitespace -./build/lib/linkage/models/base.py:38:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:39:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/models/base.py:54:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:69:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/models/base.py:82:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:83:46: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:84:37: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:89:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:92:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/models/base.py:92:38: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:93:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:114:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:124:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:130:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/models/base.py:130:30: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:137:29: W291 trailing whitespace -./build/lib/linkage/models/base.py:142:72: W291 trailing whitespace -./build/lib/linkage/models/base.py:144:65: W291 trailing whitespace -./build/lib/linkage/models/base.py:151:1: C901 '_parse_linkage_docstring' is too complex (14) -./build/lib/linkage/models/base.py:159:44: W291 trailing whitespace -./build/lib/linkage/models/base.py:161:16: W291 trailing whitespace -./build/lib/linkage/models/base.py:175:36: W291 trailing whitespace -./build/lib/linkage/models/base.py:176:71: W291 trailing whitespace -./build/lib/linkage/models/base.py:178:27: W291 trailing whitespace -./build/lib/linkage/models/base.py:179:62: W291 trailing whitespace -./build/lib/linkage/models/base.py:180:69: W291 trailing whitespace -./build/lib/linkage/models/base.py:181:50: W291 trailing whitespace -./build/lib/linkage/models/base.py:182:73: W291 trailing whitespace -./build/lib/linkage/models/base.py:184:36: W291 trailing whitespace -./build/lib/linkage/models/base.py:186:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:193:42: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:196:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:201:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:7:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/models/base.py:10:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:20:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:29:13: E722 do not use bare 'except' +./build/lib/linkage/models/base.py:32:14: W291 trailing whitespace +./build/lib/linkage/models/base.py:39:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:40:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/models/base.py:55:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:70:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/models/base.py:83:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:84:46: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:85:37: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:90:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:93:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/models/base.py:93:38: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:94:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:115:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:125:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:131:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/models/base.py:131:30: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:138:29: W291 trailing whitespace +./build/lib/linkage/models/base.py:143:72: W291 trailing whitespace +./build/lib/linkage/models/base.py:145:65: W291 trailing whitespace +./build/lib/linkage/models/base.py:152:1: C901 '_parse_linkage_docstring' is too complex (14) +./build/lib/linkage/models/base.py:153:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:160:42: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:163:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:168:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:171:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:185:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:187:67: W291 trailing whitespace +./build/lib/linkage/models/base.py:197:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:202:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:203:39: E231 missing whitespace after ',' ./build/lib/linkage/models/base.py:204:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:218:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:220:67: W291 trailing whitespace -./build/lib/linkage/models/base.py:230:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:235:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:236:39: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:212:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:213:58: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:223:1: W293 blank line contains whitespace ./build/lib/linkage/models/base.py:237:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:245:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:246:58: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:256:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:270:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:271:5: E303 too many blank lines (2) -./build/lib/linkage/models/base.py:272:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:280:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:238:5: E303 too many blank lines (2) +./build/lib/linkage/models/base.py:239:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:247:13: W291 trailing whitespace +./build/lib/linkage/models/base.py:255:52: W291 trailing whitespace +./build/lib/linkage/models/base.py:257:16: W291 trailing whitespace +./build/lib/linkage/models/base.py:274:36: W291 trailing whitespace +./build/lib/linkage/models/base.py:275:71: W291 trailing whitespace +./build/lib/linkage/models/base.py:277:27: W291 trailing whitespace +./build/lib/linkage/models/base.py:278:62: W291 trailing whitespace +./build/lib/linkage/models/base.py:279:67: W291 trailing whitespace +./build/lib/linkage/models/base.py:280:50: W291 trailing whitespace +./build/lib/linkage/models/base.py:281:73: W291 trailing whitespace +./build/lib/linkage/models/base.py:283:36: W291 trailing whitespace +./build/lib/linkage/models/base.py:288:30: W291 trailing whitespace ./build/lib/linkage/models/base.py:290:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:309:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:310:23: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:310:35: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:313:76: W291 trailing whitespace -./build/lib/linkage/models/base.py:314:57: W291 trailing whitespace -./build/lib/linkage/models/base.py:315:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:318:77: W291 trailing whitespace -./build/lib/linkage/models/base.py:319:79: W291 trailing whitespace -./build/lib/linkage/models/base.py:323:77: W291 trailing whitespace -./build/lib/linkage/models/base.py:324:72: W291 trailing whitespace -./build/lib/linkage/models/base.py:325:73: W291 trailing whitespace -./build/lib/linkage/models/base.py:332:27: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:337:70: W291 trailing whitespace -./build/lib/linkage/models/base.py:338:76: W291 trailing whitespace -./build/lib/linkage/models/base.py:339:55: W291 trailing whitespace -./build/lib/linkage/models/base.py:341:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:345:30: E231 missing whitespace after ',' -./build/lib/linkage/models/base.py:350:70: W291 trailing whitespace -./build/lib/linkage/models/base.py:351:78: W291 trailing whitespace -./build/lib/linkage/models/base.py:352:52: W291 trailing whitespace -./build/lib/linkage/models/base.py:358:30: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:300:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:320:28: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:320:34: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:322:54: W291 trailing whitespace +./build/lib/linkage/models/base.py:336:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:340:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:341:61: W291 trailing whitespace +./build/lib/linkage/models/base.py:344:26: W291 trailing whitespace +./build/lib/linkage/models/base.py:345:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:348:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:349:73: W291 trailing whitespace +./build/lib/linkage/models/base.py:350:75: W291 trailing whitespace +./build/lib/linkage/models/base.py:352:48: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:356:1: W293 blank line contains whitespace ./build/lib/linkage/models/base.py:359:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:363:74: W291 trailing whitespace -./build/lib/linkage/models/base.py:365:34: W291 trailing whitespace -./build/lib/linkage/models/base.py:372:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:376:1: W293 blank line contains whitespace -./build/lib/linkage/models/base.py:383:29: W292 no newline at end of file -./build/lib/linkage/models/ca_edta.py:8:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/models/ca_edta.py:13:1: W293 blank line contains whitespace -./build/lib/linkage/models/ca_edta.py:17:1: W293 blank line contains whitespace -./build/lib/linkage/models/ca_edta.py:21:23: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:21:35: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:27:32: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:27:35: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:27:40: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:38:44: E225 missing whitespace around operator -./build/lib/linkage/models/ca_edta.py:39:44: E225 missing whitespace around operator -./build/lib/linkage/models/ca_edta.py:40:44: E225 missing whitespace around operator -./build/lib/linkage/models/ca_edta.py:42:1: W293 blank line contains whitespace -./build/lib/linkage/models/ca_edta.py:46:36: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:47:1: W293 blank line contains whitespace -./build/lib/linkage/models/ca_edta.py:48:58: W291 trailing whitespace -./build/lib/linkage/models/ca_edta.py:50:1: W293 blank line contains whitespace -./build/lib/linkage/models/ca_edta.py:51:73: W291 trailing whitespace -./build/lib/linkage/models/ca_edta.py:52:75: W291 trailing whitespace -./build/lib/linkage/models/ca_edta.py:54:48: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:57:40: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:64:27: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:64:29: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:64:33: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:72:30: E231 missing whitespace after ',' -./build/lib/linkage/models/ca_edta.py:73:1: W293 blank line contains whitespace -./build/lib/linkage/models/ca_edta.py:77:1: W293 blank line contains whitespace -./build/lib/linkage/models/ca_edta.py:80:13: W292 no newline at end of file -./build/lib/linkage/models/six_state_edta.py:10:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/models/six_state_edta.py:29:25: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:29:28: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:29:31: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:29:34: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:29:37: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:29:40: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:29:43: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:29:46: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:29:49: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:35:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:36:79: W291 trailing whitespace -./build/lib/linkage/models/six_state_edta.py:37:82: W291 trailing whitespace -./build/lib/linkage/models/six_state_edta.py:40:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:46:50: E225 missing whitespace around operator -./build/lib/linkage/models/six_state_edta.py:49:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:51:31: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:51:36: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:51:42: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:51:48: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:51:56: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:51:61: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:54:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:56:47: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:56:53: E225 missing whitespace around operator -./build/lib/linkage/models/six_state_edta.py:56:56: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:56:62: E225 missing whitespace around operator -./build/lib/linkage/models/six_state_edta.py:58:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:61:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:66:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:360:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:361:5: E303 too many blank lines (2) +./build/lib/linkage/models/base.py:361:23: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:361:35: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:364:76: W291 trailing whitespace +./build/lib/linkage/models/base.py:365:57: W291 trailing whitespace +./build/lib/linkage/models/base.py:366:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:369:77: W291 trailing whitespace +./build/lib/linkage/models/base.py:370:79: W291 trailing whitespace +./build/lib/linkage/models/base.py:374:77: W291 trailing whitespace +./build/lib/linkage/models/base.py:375:72: W291 trailing whitespace +./build/lib/linkage/models/base.py:376:73: W291 trailing whitespace +./build/lib/linkage/models/base.py:383:27: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:388:70: W291 trailing whitespace +./build/lib/linkage/models/base.py:389:76: W291 trailing whitespace +./build/lib/linkage/models/base.py:390:55: W291 trailing whitespace +./build/lib/linkage/models/base.py:392:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:396:30: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:401:70: W291 trailing whitespace +./build/lib/linkage/models/base.py:402:78: W291 trailing whitespace +./build/lib/linkage/models/base.py:403:52: W291 trailing whitespace +./build/lib/linkage/models/base.py:409:30: E231 missing whitespace after ',' +./build/lib/linkage/models/base.py:410:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:414:74: W291 trailing whitespace +./build/lib/linkage/models/base.py:416:34: W291 trailing whitespace +./build/lib/linkage/models/base.py:423:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:427:1: W293 blank line contains whitespace +./build/lib/linkage/models/base.py:434:29: W292 no newline at end of file +./build/lib/linkage/models/ca_edta.py:6:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/models/ca_edta.py:15:1: W293 blank line contains whitespace +./build/lib/linkage/models/ca_edta.py:16:23: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:16:35: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:22:32: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:22:35: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:22:40: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:33:50: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:34:1: W293 blank line contains whitespace +./build/lib/linkage/models/ca_edta.py:39:27: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:39:29: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:39:33: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:47:30: E231 missing whitespace after ',' +./build/lib/linkage/models/ca_edta.py:48:1: W293 blank line contains whitespace +./build/lib/linkage/models/ca_edta.py:52:1: W293 blank line contains whitespace +./build/lib/linkage/models/ca_edta.py:55:13: W292 no newline at end of file +./build/lib/linkage/models/six_state_edta.py:25:25: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:25:28: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:25:31: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:25:34: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:25:37: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:25:40: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:25:43: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:25:46: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:25:49: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:31:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:32:79: W291 trailing whitespace +./build/lib/linkage/models/six_state_edta.py:33:82: W291 trailing whitespace +./build/lib/linkage/models/six_state_edta.py:36:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:42:50: E225 missing whitespace around operator +./build/lib/linkage/models/six_state_edta.py:45:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:47:31: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:47:36: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:47:42: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:47:48: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:47:56: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:47:61: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:51:41: W291 trailing whitespace +./build/lib/linkage/models/six_state_edta.py:57:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:58:5: E303 too many blank lines (2) +./build/lib/linkage/models/six_state_edta.py:58:23: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:58:35: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:60:74: W291 trailing whitespace +./build/lib/linkage/models/six_state_edta.py:61:56: W291 trailing whitespace +./build/lib/linkage/models/six_state_edta.py:62:1: W293 blank line contains whitespace ./build/lib/linkage/models/six_state_edta.py:69:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:70:73: W291 trailing whitespace -./build/lib/linkage/models/six_state_edta.py:72:48: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:76:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:73:79: W291 trailing whitespace ./build/lib/linkage/models/six_state_edta.py:79:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:80:23: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:80:35: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:82:74: W291 trailing whitespace -./build/lib/linkage/models/six_state_edta.py:83:56: W291 trailing whitespace -./build/lib/linkage/models/six_state_edta.py:84:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:91:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:95:79: W291 trailing whitespace -./build/lib/linkage/models/six_state_edta.py:101:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:103:32: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:103:35: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:103:38: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:103:41: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:103:44: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:103:47: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:103:50: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:103:53: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:104:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:110:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:114:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:118:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:121:9: E741 ambiguous variable name 'I' -./build/lib/linkage/models/six_state_edta.py:127:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:129:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:132:5: E303 too many blank lines (3) -./build/lib/linkage/models/six_state_edta.py:134:30: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:134:35: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:134:40: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:134:45: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:134:50: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:138:30: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:138:35: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:139:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:143:1: W391 blank line at end of file +./build/lib/linkage/models/six_state_edta.py:81:32: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:81:35: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:81:38: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:81:41: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:81:44: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:81:47: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:81:50: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:81:53: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:82:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:88:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:92:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:96:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:99:9: E741 ambiguous variable name 'I' +./build/lib/linkage/models/six_state_edta.py:105:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:107:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:110:5: E303 too many blank lines (3) +./build/lib/linkage/models/six_state_edta.py:112:30: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:112:35: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:112:40: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:112:45: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:112:50: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:116:30: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:116:35: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:117:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:121:1: W391 blank line at end of file ./build/lib/linkage/organizer/__init__.py:1:1: F401 'linkage.organizer.global_model.GlobalModel' imported but unused ./build/lib/linkage/organizer/__init__.py:1:55: W292 no newline at end of file ./build/lib/linkage/organizer/global_fit.py:10:1: E302 expected 2 blank lines, found 1 @@ -363,89 +432,95 @@ ./build/lib/linkage/organizer/global_fit.py:337:1: W293 blank line contains whitespace ./build/lib/linkage/organizer/global_fit.py:337:9: W292 no newline at end of file ./build/lib/linkage/organizer/global_model.py:10:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/organizer/global_model.py:12:22: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:12:32: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:15:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:37:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:48:61: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:50:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:56:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:57:59: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:59:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:60:58: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:67:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:73:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:81:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:86:77: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:88:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:98:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:99:47: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:114:41: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:121:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:124:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:132:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:134:5: E303 too many blank lines (2) -./build/lib/linkage/organizer/global_model.py:136:69: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:139:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:145:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:148:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:149:61: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:150:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:153:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:163:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:168:49: E127 continuation line over-indented for visual indent -./build/lib/linkage/organizer/global_model.py:169:48: E127 continuation line over-indented for visual indent -./build/lib/linkage/organizer/global_model.py:172:57: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:17:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:35:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:42:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:53:61: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:55:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:61:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:62:59: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:64:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:65:58: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:72:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:78:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:86:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:91:77: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:93:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:103:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:104:47: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:119:41: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:126:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:129:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:135:27: E225 missing whitespace around operator +./build/lib/linkage/organizer/global_model.py:158:68: E221 multiple spaces before operator +./build/lib/linkage/organizer/global_model.py:159:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:161:5: E303 too many blank lines (2) +./build/lib/linkage/organizer/global_model.py:163:69: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:166:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:172:1: W293 blank line contains whitespace ./build/lib/linkage/organizer/global_model.py:175:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:176:61: E231 missing whitespace after ',' ./build/lib/linkage/organizer/global_model.py:177:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:179:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:181:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:182:75: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:183:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:186:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:199:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:204:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:213:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:218:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:223:48: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:227:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:228:5: E303 too many blank lines (2) -./build/lib/linkage/organizer/global_model.py:228:19: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:229:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:232:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:244:78: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:246:59: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:249:56: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:250:53: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:253:40: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:260:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:269:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:290:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:297:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:180:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:191:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:196:49: E127 continuation line over-indented for visual indent +./build/lib/linkage/organizer/global_model.py:197:48: E127 continuation line over-indented for visual indent +./build/lib/linkage/organizer/global_model.py:200:57: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:204:78: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:205:23: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:212:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:213:53: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:215:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:217:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:219:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:221:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:222:75: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:223:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:226:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:240:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:245:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:257:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:262:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:267:48: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:271:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:272:5: E303 too many blank lines (2) +./build/lib/linkage/organizer/global_model.py:272:19: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:273:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:276:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:288:78: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:290:59: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:293:56: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:294:53: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:297:40: E231 missing whitespace after ',' ./build/lib/linkage/organizer/global_model.py:304:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:308:75: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:309:15: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:312:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:316:75: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:317:15: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:320:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:324:25: E231 missing whitespace after ':' -./build/lib/linkage/organizer/global_model.py:325:27: E231 missing whitespace after ':' -./build/lib/linkage/organizer/global_model.py:326:26: E231 missing whitespace after ':' -./build/lib/linkage/organizer/global_model.py:335:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:338:34: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:344:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:345:36: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:355:52: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:358:52: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:359:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:366:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:366:9: W292 no newline at end of file +./build/lib/linkage/organizer/global_model.py:313:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:334:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:341:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:348:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:352:75: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:353:15: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:356:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:360:75: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:361:15: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:364:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:368:25: E231 missing whitespace after ':' +./build/lib/linkage/organizer/global_model.py:369:27: E231 missing whitespace after ':' +./build/lib/linkage/organizer/global_model.py:370:26: E231 missing whitespace after ':' +./build/lib/linkage/organizer/global_model.py:379:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:382:34: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:388:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:389:36: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:399:52: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:402:52: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:403:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:410:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:410:9: W292 no newline at end of file ./src/linkage/__init__.py:2:1: F401 'linkage.experiment.Experiment' imported but unused ./src/linkage/__init__.py:3:1: F401 'linkage.organizer.GlobalModel' imported but unused ./src/linkage/__init__.py:12:52: E231 missing whitespace after ',' ./src/linkage/__init__.py:13:36: W292 no newline at end of file ./src/linkage/experiment/__init__.py:2:1: F401 'linkage.experiment.experiment.Experiment' imported but unused +./src/linkage/experiment/__init__.py:3:1: W391 blank line at end of file ./src/linkage/experiment/baseline_corrector.py:4:1: E302 expected 2 blank lines, found 1 ./src/linkage/experiment/baseline_corrector.py:4:25: E231 missing whitespace after ',' ./src/linkage/experiment/baseline_corrector.py:4:27: E231 missing whitespace after ',' @@ -467,342 +542,369 @@ ./src/linkage/experiment/baseline_corrector.py:43:18: E231 missing whitespace after ',' ./src/linkage/experiment/baseline_corrector.py:43:45: E231 missing whitespace after ',' ./src/linkage/experiment/baseline_corrector.py:43:49: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:6:1: E302 expected 2 blank lines, found 1 -./src/linkage/experiment/experiment.py:16:42: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:25:76: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:27:91: W291 trailing whitespace -./src/linkage/experiment/experiment.py:29:71: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:29:84: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:30:31: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:34:49: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:34:66: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:35:1: W293 blank line contains whitespace -./src/linkage/experiment/experiment.py:36:46: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:40:49: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:59:1: W293 blank line contains whitespace -./src/linkage/experiment/experiment.py:74:35: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:79:1: W293 blank line contains whitespace -./src/linkage/experiment/experiment.py:84:51: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:87:46: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:90:1: W293 blank line contains whitespace -./src/linkage/experiment/experiment.py:101:53: E231 missing whitespace after ':' -./src/linkage/experiment/experiment.py:102:63: E231 missing whitespace after ':' -./src/linkage/experiment/experiment.py:103:56: E231 missing whitespace after ':' -./src/linkage/experiment/experiment.py:104:1: W293 blank line contains whitespace -./src/linkage/experiment/experiment.py:105:34: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:105:45: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:116:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:3:1: E302 expected 2 blank lines, found 1 -./src/linkage/experiment/experimental_point.py:6:13: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:8:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:18:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:38:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:48:1: E303 too many blank lines (3) -./src/linkage/experiment/experimental_point.py:50:66: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:51:67: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:63:47: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:64:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:92:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:95:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:96:24: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:96:30: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:98:75: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:102:49: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:103:42: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:111:49: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:124:38: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:125:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:142:75: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:149:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:155:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:159:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:160:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:161:5: E303 too many blank lines (2) -./src/linkage/experiment/experimental_point.py:161:24: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:161:35: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:161:41: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:165:17: W291 trailing whitespace -./src/linkage/experiment/experimental_point.py:174:41: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:174:76: E231 missing whitespace after ',' -./src/linkage/experiment/experimental_point.py:175:1: W293 blank line contains whitespace -./src/linkage/experiment/experimental_point.py:176:35: W292 no newline at end of file -./src/linkage/experiment/titrator.py:6:1: C901 'titrator' is too complex (11) +./src/linkage/experiment/experiment.py:9:1: E302 expected 2 blank lines, found 1 +./src/linkage/experiment/experiment.py:18:26: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:21:38: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:23:38: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:26:38: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:26:47: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:37:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:48:60: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:51:5: E303 too many blank lines (2) +./src/linkage/experiment/experiment.py:51:87: W291 trailing whitespace +./src/linkage/experiment/experiment.py:53:55: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:53:68: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:54:27: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:58:39: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:58:50: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:76:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:90:43: W291 trailing whitespace +./src/linkage/experiment/experiment.py:98:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:113:35: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:118:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:123:51: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:126:46: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:129:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:140:53: E231 missing whitespace after ':' +./src/linkage/experiment/experiment.py:141:63: E231 missing whitespace after ':' +./src/linkage/experiment/experiment.py:142:56: E231 missing whitespace after ':' +./src/linkage/experiment/experiment.py:143:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:144:34: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:144:45: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:155:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:171:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:174:43: W292 no newline at end of file +./src/linkage/experiment/point/__init__.py:1:1: W391 blank line at end of file +./src/linkage/experiment/point/experimental_point.py:1:1: F401 'numpy as np' imported but unused +./src/linkage/experiment/point/experimental_point.py:3:1: E302 expected 2 blank lines, found 1 +./src/linkage/experiment/point/experimental_point.py:6:13: W291 trailing whitespace +./src/linkage/experiment/point/experimental_point.py:8:1: W293 blank line contains whitespace +./src/linkage/experiment/point/experimental_point.py:19:1: W293 blank line contains whitespace +./src/linkage/experiment/point/experimental_point.py:40:1: W293 blank line contains whitespace +./src/linkage/experiment/point/experimental_point.py:47:1: W391 blank line at end of file +./src/linkage/experiment/point/itc_point.py:6:1: E302 expected 2 blank lines, found 1 +./src/linkage/experiment/point/itc_point.py:9:49: W291 trailing whitespace +./src/linkage/experiment/point/itc_point.py:25:38: W291 trailing whitespace +./src/linkage/experiment/point/itc_point.py:26:1: W293 blank line contains whitespace +./src/linkage/experiment/point/itc_point.py:42:78: W291 trailing whitespace +./src/linkage/experiment/point/itc_point.py:46:75: W291 trailing whitespace +./src/linkage/experiment/point/itc_point.py:53:76: W291 trailing whitespace +./src/linkage/experiment/point/itc_point.py:56:75: W291 trailing whitespace +./src/linkage/experiment/point/itc_point.py:59:1: W293 blank line contains whitespace +./src/linkage/experiment/point/itc_point.py:66:1: W293 blank line contains whitespace +./src/linkage/experiment/point/itc_point.py:76:60: W291 trailing whitespace +./src/linkage/experiment/point/itc_point.py:79:1: W293 blank line contains whitespace +./src/linkage/experiment/point/itc_point.py:80:24: E231 missing whitespace after ',' +./src/linkage/experiment/point/itc_point.py:80:35: E231 missing whitespace after ',' +./src/linkage/experiment/point/itc_point.py:80:41: E231 missing whitespace after ',' +./src/linkage/experiment/point/itc_point.py:84:17: W291 trailing whitespace +./src/linkage/experiment/point/itc_point.py:93:1: W293 blank line contains whitespace +./src/linkage/experiment/point/itc_point.py:97:20: E221 multiple spaces before operator +./src/linkage/experiment/point/itc_point.py:97:51: E231 missing whitespace after ',' +./src/linkage/experiment/point/itc_point.py:98:53: E231 missing whitespace after ',' +./src/linkage/experiment/point/itc_point.py:103:32: W291 trailing whitespace +./src/linkage/experiment/point/itc_point.py:105:71: E231 missing whitespace after ',' +./src/linkage/experiment/point/itc_point.py:107:26: W292 no newline at end of file +./src/linkage/experiment/point/spec_point.py:6:1: E302 expected 2 blank lines, found 1 +./src/linkage/experiment/point/spec_point.py:8:66: W291 trailing whitespace +./src/linkage/experiment/point/spec_point.py:9:67: W291 trailing whitespace +./src/linkage/experiment/point/spec_point.py:22:47: W291 trailing whitespace +./src/linkage/experiment/point/spec_point.py:23:1: W293 blank line contains whitespace +./src/linkage/experiment/point/spec_point.py:39:78: W291 trailing whitespace +./src/linkage/experiment/point/spec_point.py:55:1: W293 blank line contains whitespace +./src/linkage/experiment/point/spec_point.py:58:1: W293 blank line contains whitespace +./src/linkage/experiment/point/spec_point.py:59:24: E231 missing whitespace after ',' +./src/linkage/experiment/point/spec_point.py:59:30: E231 missing whitespace after ',' +./src/linkage/experiment/point/spec_point.py:61:75: W291 trailing whitespace +./src/linkage/experiment/point/spec_point.py:65:49: E231 missing whitespace after ',' +./src/linkage/experiment/point/spec_point.py:66:42: E231 missing whitespace after ',' +./src/linkage/experiment/point/spec_point.py:70:1: W391 blank line at end of file ./src/linkage/experiment/titrator.py:6:1: E302 expected 2 blank lines, found 1 -./src/linkage/experiment/titrator.py:13:55: W291 trailing whitespace -./src/linkage/experiment/titrator.py:14:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:21:32: W291 trailing whitespace -./src/linkage/experiment/titrator.py:26:32: W291 trailing whitespace -./src/linkage/experiment/titrator.py:31:51: W291 trailing whitespace -./src/linkage/experiment/titrator.py:33:90: W291 trailing whitespace -./src/linkage/experiment/titrator.py:34:67: W291 trailing whitespace -./src/linkage/experiment/titrator.py:35:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:42:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:46:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:51:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:59:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:61:47: E231 missing whitespace after ',' -./src/linkage/experiment/titrator.py:62:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:70:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:100:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:109:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:8:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:9:42: E231 missing whitespace after ',' +./src/linkage/experiment/titrator.py:13:45: E231 missing whitespace after ',' +./src/linkage/experiment/titrator.py:20:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:25:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:36:1: E302 expected 2 blank lines, found 1 +./src/linkage/experiment/titrator.py:54:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:63:1: E302 expected 2 blank lines, found 1 +./src/linkage/experiment/titrator.py:68:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:81:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:91:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:99:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:102:1: E303 too many blank lines (3) +./src/linkage/experiment/titrator.py:109:55: W291 trailing whitespace +./src/linkage/experiment/titrator.py:110:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:117:32: W291 trailing whitespace +./src/linkage/experiment/titrator.py:122:32: W291 trailing whitespace +./src/linkage/experiment/titrator.py:127:51: W291 trailing whitespace +./src/linkage/experiment/titrator.py:129:90: W291 trailing whitespace +./src/linkage/experiment/titrator.py:130:67: W291 trailing whitespace +./src/linkage/experiment/titrator.py:131:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:141:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:143:47: E231 missing whitespace after ',' +./src/linkage/experiment/titrator.py:144:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:152:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:154:5: E303 too many blank lines (2) +./src/linkage/experiment/titrator.py:166:1: W293 blank line contains whitespace ./src/linkage/models/__init__.py:2:1: F401 'linkage.models.six_state_edta.SixStateEDTA' imported but unused ./src/linkage/models/__init__.py:3:1: F401 'linkage.models.ca_edta.CaEDTA' imported but unused -./src/linkage/models/base.py:6:1: E302 expected 2 blank lines, found 1 -./src/linkage/models/base.py:9:1: W293 blank line contains whitespace -./src/linkage/models/base.py:19:1: W293 blank line contains whitespace -./src/linkage/models/base.py:28:13: E722 do not use bare 'except' -./src/linkage/models/base.py:31:14: W291 trailing whitespace -./src/linkage/models/base.py:38:1: W293 blank line contains whitespace -./src/linkage/models/base.py:39:1: E302 expected 2 blank lines, found 1 -./src/linkage/models/base.py:54:1: W293 blank line contains whitespace -./src/linkage/models/base.py:69:1: E302 expected 2 blank lines, found 1 -./src/linkage/models/base.py:82:1: W293 blank line contains whitespace -./src/linkage/models/base.py:83:46: E231 missing whitespace after ',' -./src/linkage/models/base.py:84:37: E231 missing whitespace after ',' -./src/linkage/models/base.py:89:1: W293 blank line contains whitespace -./src/linkage/models/base.py:92:1: E302 expected 2 blank lines, found 1 -./src/linkage/models/base.py:92:38: E231 missing whitespace after ',' -./src/linkage/models/base.py:93:1: W293 blank line contains whitespace -./src/linkage/models/base.py:114:1: W293 blank line contains whitespace -./src/linkage/models/base.py:124:1: W293 blank line contains whitespace -./src/linkage/models/base.py:130:1: E302 expected 2 blank lines, found 1 -./src/linkage/models/base.py:130:30: E231 missing whitespace after ',' -./src/linkage/models/base.py:137:29: W291 trailing whitespace -./src/linkage/models/base.py:142:72: W291 trailing whitespace -./src/linkage/models/base.py:144:65: W291 trailing whitespace -./src/linkage/models/base.py:151:1: C901 '_parse_linkage_docstring' is too complex (14) -./src/linkage/models/base.py:159:44: W291 trailing whitespace -./src/linkage/models/base.py:161:16: W291 trailing whitespace -./src/linkage/models/base.py:175:36: W291 trailing whitespace -./src/linkage/models/base.py:176:71: W291 trailing whitespace -./src/linkage/models/base.py:178:27: W291 trailing whitespace -./src/linkage/models/base.py:179:62: W291 trailing whitespace -./src/linkage/models/base.py:180:69: W291 trailing whitespace -./src/linkage/models/base.py:181:50: W291 trailing whitespace -./src/linkage/models/base.py:182:73: W291 trailing whitespace -./src/linkage/models/base.py:184:36: W291 trailing whitespace -./src/linkage/models/base.py:186:1: W293 blank line contains whitespace -./src/linkage/models/base.py:193:42: E231 missing whitespace after ',' -./src/linkage/models/base.py:196:1: W293 blank line contains whitespace -./src/linkage/models/base.py:201:1: W293 blank line contains whitespace +./src/linkage/models/base.py:7:1: E302 expected 2 blank lines, found 1 +./src/linkage/models/base.py:10:1: W293 blank line contains whitespace +./src/linkage/models/base.py:20:1: W293 blank line contains whitespace +./src/linkage/models/base.py:29:13: E722 do not use bare 'except' +./src/linkage/models/base.py:32:14: W291 trailing whitespace +./src/linkage/models/base.py:39:1: W293 blank line contains whitespace +./src/linkage/models/base.py:40:1: E302 expected 2 blank lines, found 1 +./src/linkage/models/base.py:55:1: W293 blank line contains whitespace +./src/linkage/models/base.py:70:1: E302 expected 2 blank lines, found 1 +./src/linkage/models/base.py:83:1: W293 blank line contains whitespace +./src/linkage/models/base.py:84:46: E231 missing whitespace after ',' +./src/linkage/models/base.py:85:37: E231 missing whitespace after ',' +./src/linkage/models/base.py:90:1: W293 blank line contains whitespace +./src/linkage/models/base.py:93:1: E302 expected 2 blank lines, found 1 +./src/linkage/models/base.py:93:38: E231 missing whitespace after ',' +./src/linkage/models/base.py:94:1: W293 blank line contains whitespace +./src/linkage/models/base.py:115:1: W293 blank line contains whitespace +./src/linkage/models/base.py:125:1: W293 blank line contains whitespace +./src/linkage/models/base.py:131:1: E302 expected 2 blank lines, found 1 +./src/linkage/models/base.py:131:30: E231 missing whitespace after ',' +./src/linkage/models/base.py:138:29: W291 trailing whitespace +./src/linkage/models/base.py:143:72: W291 trailing whitespace +./src/linkage/models/base.py:145:65: W291 trailing whitespace +./src/linkage/models/base.py:152:1: C901 '_parse_linkage_docstring' is too complex (14) +./src/linkage/models/base.py:153:1: W293 blank line contains whitespace +./src/linkage/models/base.py:160:42: E231 missing whitespace after ',' +./src/linkage/models/base.py:163:1: W293 blank line contains whitespace +./src/linkage/models/base.py:168:1: W293 blank line contains whitespace +./src/linkage/models/base.py:171:1: W293 blank line contains whitespace +./src/linkage/models/base.py:185:1: W293 blank line contains whitespace +./src/linkage/models/base.py:187:67: W291 trailing whitespace +./src/linkage/models/base.py:197:1: W293 blank line contains whitespace +./src/linkage/models/base.py:202:1: W293 blank line contains whitespace +./src/linkage/models/base.py:203:39: E231 missing whitespace after ',' ./src/linkage/models/base.py:204:1: W293 blank line contains whitespace -./src/linkage/models/base.py:218:1: W293 blank line contains whitespace -./src/linkage/models/base.py:220:67: W291 trailing whitespace -./src/linkage/models/base.py:230:1: W293 blank line contains whitespace -./src/linkage/models/base.py:235:1: W293 blank line contains whitespace -./src/linkage/models/base.py:236:39: E231 missing whitespace after ',' +./src/linkage/models/base.py:212:1: W293 blank line contains whitespace +./src/linkage/models/base.py:213:58: E231 missing whitespace after ',' +./src/linkage/models/base.py:223:1: W293 blank line contains whitespace ./src/linkage/models/base.py:237:1: W293 blank line contains whitespace -./src/linkage/models/base.py:245:1: W293 blank line contains whitespace -./src/linkage/models/base.py:246:58: E231 missing whitespace after ',' -./src/linkage/models/base.py:256:1: W293 blank line contains whitespace -./src/linkage/models/base.py:270:1: W293 blank line contains whitespace -./src/linkage/models/base.py:271:5: E303 too many blank lines (2) -./src/linkage/models/base.py:272:1: W293 blank line contains whitespace -./src/linkage/models/base.py:280:1: W293 blank line contains whitespace +./src/linkage/models/base.py:238:5: E303 too many blank lines (2) +./src/linkage/models/base.py:239:1: W293 blank line contains whitespace +./src/linkage/models/base.py:247:13: W291 trailing whitespace +./src/linkage/models/base.py:255:52: W291 trailing whitespace +./src/linkage/models/base.py:257:16: W291 trailing whitespace +./src/linkage/models/base.py:274:36: W291 trailing whitespace +./src/linkage/models/base.py:275:71: W291 trailing whitespace +./src/linkage/models/base.py:277:27: W291 trailing whitespace +./src/linkage/models/base.py:278:62: W291 trailing whitespace +./src/linkage/models/base.py:279:67: W291 trailing whitespace +./src/linkage/models/base.py:280:50: W291 trailing whitespace +./src/linkage/models/base.py:281:73: W291 trailing whitespace +./src/linkage/models/base.py:283:36: W291 trailing whitespace +./src/linkage/models/base.py:288:30: W291 trailing whitespace ./src/linkage/models/base.py:290:1: W293 blank line contains whitespace -./src/linkage/models/base.py:309:1: W293 blank line contains whitespace -./src/linkage/models/base.py:310:23: E231 missing whitespace after ',' -./src/linkage/models/base.py:310:35: E231 missing whitespace after ',' -./src/linkage/models/base.py:313:76: W291 trailing whitespace -./src/linkage/models/base.py:314:57: W291 trailing whitespace -./src/linkage/models/base.py:315:1: W293 blank line contains whitespace -./src/linkage/models/base.py:318:77: W291 trailing whitespace -./src/linkage/models/base.py:319:79: W291 trailing whitespace -./src/linkage/models/base.py:323:77: W291 trailing whitespace -./src/linkage/models/base.py:324:72: W291 trailing whitespace -./src/linkage/models/base.py:325:73: W291 trailing whitespace -./src/linkage/models/base.py:332:27: E231 missing whitespace after ',' -./src/linkage/models/base.py:337:70: W291 trailing whitespace -./src/linkage/models/base.py:338:76: W291 trailing whitespace -./src/linkage/models/base.py:339:55: W291 trailing whitespace -./src/linkage/models/base.py:341:1: W293 blank line contains whitespace -./src/linkage/models/base.py:345:30: E231 missing whitespace after ',' -./src/linkage/models/base.py:350:70: W291 trailing whitespace -./src/linkage/models/base.py:351:78: W291 trailing whitespace -./src/linkage/models/base.py:352:52: W291 trailing whitespace -./src/linkage/models/base.py:358:30: E231 missing whitespace after ',' +./src/linkage/models/base.py:300:1: W293 blank line contains whitespace +./src/linkage/models/base.py:320:28: E231 missing whitespace after ',' +./src/linkage/models/base.py:320:34: E231 missing whitespace after ',' +./src/linkage/models/base.py:322:54: W291 trailing whitespace +./src/linkage/models/base.py:336:1: W293 blank line contains whitespace +./src/linkage/models/base.py:340:1: W293 blank line contains whitespace +./src/linkage/models/base.py:341:61: W291 trailing whitespace +./src/linkage/models/base.py:344:26: W291 trailing whitespace +./src/linkage/models/base.py:345:1: W293 blank line contains whitespace +./src/linkage/models/base.py:348:1: W293 blank line contains whitespace +./src/linkage/models/base.py:349:73: W291 trailing whitespace +./src/linkage/models/base.py:350:75: W291 trailing whitespace +./src/linkage/models/base.py:352:48: E231 missing whitespace after ',' +./src/linkage/models/base.py:356:1: W293 blank line contains whitespace ./src/linkage/models/base.py:359:1: W293 blank line contains whitespace -./src/linkage/models/base.py:363:74: W291 trailing whitespace -./src/linkage/models/base.py:365:34: W291 trailing whitespace -./src/linkage/models/base.py:372:1: W293 blank line contains whitespace -./src/linkage/models/base.py:376:1: W293 blank line contains whitespace -./src/linkage/models/base.py:383:29: W292 no newline at end of file -./src/linkage/models/ca_edta.py:8:1: E302 expected 2 blank lines, found 1 -./src/linkage/models/ca_edta.py:13:1: W293 blank line contains whitespace -./src/linkage/models/ca_edta.py:17:1: W293 blank line contains whitespace -./src/linkage/models/ca_edta.py:21:23: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:21:35: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:27:32: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:27:35: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:27:40: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:38:44: E225 missing whitespace around operator -./src/linkage/models/ca_edta.py:39:44: E225 missing whitespace around operator -./src/linkage/models/ca_edta.py:40:44: E225 missing whitespace around operator -./src/linkage/models/ca_edta.py:42:1: W293 blank line contains whitespace -./src/linkage/models/ca_edta.py:46:36: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:47:1: W293 blank line contains whitespace -./src/linkage/models/ca_edta.py:48:58: W291 trailing whitespace -./src/linkage/models/ca_edta.py:50:1: W293 blank line contains whitespace -./src/linkage/models/ca_edta.py:51:73: W291 trailing whitespace -./src/linkage/models/ca_edta.py:52:75: W291 trailing whitespace -./src/linkage/models/ca_edta.py:54:48: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:57:40: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:64:27: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:64:29: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:64:33: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:72:30: E231 missing whitespace after ',' -./src/linkage/models/ca_edta.py:73:1: W293 blank line contains whitespace -./src/linkage/models/ca_edta.py:77:1: W293 blank line contains whitespace -./src/linkage/models/ca_edta.py:80:13: W292 no newline at end of file -./src/linkage/models/six_state_edta.py:10:1: E302 expected 2 blank lines, found 1 -./src/linkage/models/six_state_edta.py:29:25: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:29:28: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:29:31: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:29:34: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:29:37: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:29:40: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:29:43: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:29:46: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:29:49: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:35:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:36:79: W291 trailing whitespace -./src/linkage/models/six_state_edta.py:37:82: W291 trailing whitespace -./src/linkage/models/six_state_edta.py:40:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:46:50: E225 missing whitespace around operator -./src/linkage/models/six_state_edta.py:49:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:51:31: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:51:36: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:51:42: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:51:48: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:51:56: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:51:61: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:54:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:56:47: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:56:53: E225 missing whitespace around operator -./src/linkage/models/six_state_edta.py:56:56: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:56:62: E225 missing whitespace around operator -./src/linkage/models/six_state_edta.py:58:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:61:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:66:1: W293 blank line contains whitespace +./src/linkage/models/base.py:360:1: W293 blank line contains whitespace +./src/linkage/models/base.py:361:5: E303 too many blank lines (2) +./src/linkage/models/base.py:361:23: E231 missing whitespace after ',' +./src/linkage/models/base.py:361:35: E231 missing whitespace after ',' +./src/linkage/models/base.py:364:76: W291 trailing whitespace +./src/linkage/models/base.py:365:57: W291 trailing whitespace +./src/linkage/models/base.py:366:1: W293 blank line contains whitespace +./src/linkage/models/base.py:369:77: W291 trailing whitespace +./src/linkage/models/base.py:370:79: W291 trailing whitespace +./src/linkage/models/base.py:374:77: W291 trailing whitespace +./src/linkage/models/base.py:375:72: W291 trailing whitespace +./src/linkage/models/base.py:376:73: W291 trailing whitespace +./src/linkage/models/base.py:383:27: E231 missing whitespace after ',' +./src/linkage/models/base.py:388:70: W291 trailing whitespace +./src/linkage/models/base.py:389:76: W291 trailing whitespace +./src/linkage/models/base.py:390:55: W291 trailing whitespace +./src/linkage/models/base.py:392:1: W293 blank line contains whitespace +./src/linkage/models/base.py:396:30: E231 missing whitespace after ',' +./src/linkage/models/base.py:401:70: W291 trailing whitespace +./src/linkage/models/base.py:402:78: W291 trailing whitespace +./src/linkage/models/base.py:403:52: W291 trailing whitespace +./src/linkage/models/base.py:409:30: E231 missing whitespace after ',' +./src/linkage/models/base.py:410:1: W293 blank line contains whitespace +./src/linkage/models/base.py:414:74: W291 trailing whitespace +./src/linkage/models/base.py:416:34: W291 trailing whitespace +./src/linkage/models/base.py:423:1: W293 blank line contains whitespace +./src/linkage/models/base.py:427:1: W293 blank line contains whitespace +./src/linkage/models/base.py:434:29: W292 no newline at end of file +./src/linkage/models/ca_edta.py:6:1: E302 expected 2 blank lines, found 1 +./src/linkage/models/ca_edta.py:15:1: W293 blank line contains whitespace +./src/linkage/models/ca_edta.py:16:23: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:16:35: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:22:32: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:22:35: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:22:40: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:33:50: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:34:1: W293 blank line contains whitespace +./src/linkage/models/ca_edta.py:39:27: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:39:29: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:39:33: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:47:30: E231 missing whitespace after ',' +./src/linkage/models/ca_edta.py:48:1: W293 blank line contains whitespace +./src/linkage/models/ca_edta.py:52:1: W293 blank line contains whitespace +./src/linkage/models/ca_edta.py:55:13: W292 no newline at end of file +./src/linkage/models/six_state_edta.py:25:25: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:25:28: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:25:31: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:25:34: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:25:37: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:25:40: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:25:43: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:25:46: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:25:49: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:31:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:32:79: W291 trailing whitespace +./src/linkage/models/six_state_edta.py:33:82: W291 trailing whitespace +./src/linkage/models/six_state_edta.py:36:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:42:50: E225 missing whitespace around operator +./src/linkage/models/six_state_edta.py:45:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:47:31: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:47:36: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:47:42: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:47:48: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:47:56: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:47:61: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:51:41: W291 trailing whitespace +./src/linkage/models/six_state_edta.py:57:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:58:5: E303 too many blank lines (2) +./src/linkage/models/six_state_edta.py:58:23: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:58:35: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:60:74: W291 trailing whitespace +./src/linkage/models/six_state_edta.py:61:56: W291 trailing whitespace +./src/linkage/models/six_state_edta.py:62:1: W293 blank line contains whitespace ./src/linkage/models/six_state_edta.py:69:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:70:73: W291 trailing whitespace -./src/linkage/models/six_state_edta.py:72:48: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:76:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:73:79: W291 trailing whitespace ./src/linkage/models/six_state_edta.py:79:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:80:23: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:80:35: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:82:74: W291 trailing whitespace -./src/linkage/models/six_state_edta.py:83:56: W291 trailing whitespace -./src/linkage/models/six_state_edta.py:84:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:91:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:95:79: W291 trailing whitespace -./src/linkage/models/six_state_edta.py:101:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:103:32: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:103:35: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:103:38: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:103:41: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:103:44: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:103:47: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:103:50: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:103:53: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:104:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:110:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:114:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:118:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:121:9: E741 ambiguous variable name 'I' -./src/linkage/models/six_state_edta.py:127:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:129:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:132:5: E303 too many blank lines (3) -./src/linkage/models/six_state_edta.py:134:30: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:134:35: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:134:40: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:134:45: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:134:50: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:138:30: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:138:35: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:139:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:143:1: W391 blank line at end of file +./src/linkage/models/six_state_edta.py:81:32: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:81:35: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:81:38: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:81:41: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:81:44: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:81:47: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:81:50: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:81:53: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:82:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:88:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:92:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:96:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:99:9: E741 ambiguous variable name 'I' +./src/linkage/models/six_state_edta.py:105:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:107:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:110:5: E303 too many blank lines (3) +./src/linkage/models/six_state_edta.py:112:30: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:112:35: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:112:40: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:112:45: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:112:50: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:116:30: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:116:35: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:117:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:121:1: W391 blank line at end of file ./src/linkage/organizer/__init__.py:1:1: F401 'linkage.organizer.global_model.GlobalModel' imported but unused ./src/linkage/organizer/__init__.py:1:55: W292 no newline at end of file ./src/linkage/organizer/global_model.py:10:1: E302 expected 2 blank lines, found 1 -./src/linkage/organizer/global_model.py:12:22: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:12:32: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:15:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:37:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:48:61: W291 trailing whitespace -./src/linkage/organizer/global_model.py:50:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:56:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:57:59: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:59:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:60:58: W291 trailing whitespace -./src/linkage/organizer/global_model.py:67:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:73:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:81:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:86:77: W291 trailing whitespace -./src/linkage/organizer/global_model.py:88:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:98:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:99:47: W291 trailing whitespace -./src/linkage/organizer/global_model.py:114:41: W291 trailing whitespace -./src/linkage/organizer/global_model.py:121:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:124:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:132:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:134:5: E303 too many blank lines (2) -./src/linkage/organizer/global_model.py:136:69: W291 trailing whitespace -./src/linkage/organizer/global_model.py:139:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:145:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:148:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:149:61: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:150:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:153:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:163:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:168:49: E127 continuation line over-indented for visual indent -./src/linkage/organizer/global_model.py:169:48: E127 continuation line over-indented for visual indent -./src/linkage/organizer/global_model.py:172:57: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:17:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:35:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:42:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:53:61: W291 trailing whitespace +./src/linkage/organizer/global_model.py:55:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:61:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:62:59: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:64:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:65:58: W291 trailing whitespace +./src/linkage/organizer/global_model.py:72:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:78:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:86:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:91:77: W291 trailing whitespace +./src/linkage/organizer/global_model.py:93:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:103:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:104:47: W291 trailing whitespace +./src/linkage/organizer/global_model.py:119:41: W291 trailing whitespace +./src/linkage/organizer/global_model.py:126:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:129:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:135:27: E225 missing whitespace around operator +./src/linkage/organizer/global_model.py:158:68: E221 multiple spaces before operator +./src/linkage/organizer/global_model.py:159:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:161:5: E303 too many blank lines (2) +./src/linkage/organizer/global_model.py:163:69: W291 trailing whitespace +./src/linkage/organizer/global_model.py:166:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:172:1: W293 blank line contains whitespace ./src/linkage/organizer/global_model.py:175:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:176:61: E231 missing whitespace after ',' ./src/linkage/organizer/global_model.py:177:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:179:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:181:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:182:75: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:183:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:186:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:199:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:204:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:213:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:218:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:223:48: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:227:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:228:5: E303 too many blank lines (2) -./src/linkage/organizer/global_model.py:228:19: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:229:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:232:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:244:78: W291 trailing whitespace -./src/linkage/organizer/global_model.py:246:59: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:249:56: W291 trailing whitespace -./src/linkage/organizer/global_model.py:250:53: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:253:40: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:260:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:269:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:290:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:297:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:180:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:191:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:196:49: E127 continuation line over-indented for visual indent +./src/linkage/organizer/global_model.py:197:48: E127 continuation line over-indented for visual indent +./src/linkage/organizer/global_model.py:200:57: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:204:78: W291 trailing whitespace +./src/linkage/organizer/global_model.py:205:23: W291 trailing whitespace +./src/linkage/organizer/global_model.py:212:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:213:53: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:215:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:217:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:219:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:221:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:222:75: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:223:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:226:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:240:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:245:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:257:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:262:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:267:48: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:271:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:272:5: E303 too many blank lines (2) +./src/linkage/organizer/global_model.py:272:19: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:273:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:276:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:288:78: W291 trailing whitespace +./src/linkage/organizer/global_model.py:290:59: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:293:56: W291 trailing whitespace +./src/linkage/organizer/global_model.py:294:53: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:297:40: E231 missing whitespace after ',' ./src/linkage/organizer/global_model.py:304:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:308:75: W291 trailing whitespace -./src/linkage/organizer/global_model.py:309:15: W291 trailing whitespace -./src/linkage/organizer/global_model.py:312:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:316:75: W291 trailing whitespace -./src/linkage/organizer/global_model.py:317:15: W291 trailing whitespace -./src/linkage/organizer/global_model.py:320:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:324:25: E231 missing whitespace after ':' -./src/linkage/organizer/global_model.py:325:27: E231 missing whitespace after ':' -./src/linkage/organizer/global_model.py:326:26: E231 missing whitespace after ':' -./src/linkage/organizer/global_model.py:335:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:338:34: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:344:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:345:36: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:355:52: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:358:52: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:359:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:366:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:366:9: W292 no newline at end of file +./src/linkage/organizer/global_model.py:313:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:334:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:341:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:348:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:352:75: W291 trailing whitespace +./src/linkage/organizer/global_model.py:353:15: W291 trailing whitespace +./src/linkage/organizer/global_model.py:356:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:360:75: W291 trailing whitespace +./src/linkage/organizer/global_model.py:361:15: W291 trailing whitespace +./src/linkage/organizer/global_model.py:364:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:368:25: E231 missing whitespace after ':' +./src/linkage/organizer/global_model.py:369:27: E231 missing whitespace after ':' +./src/linkage/organizer/global_model.py:370:26: E231 missing whitespace after ':' +./src/linkage/organizer/global_model.py:379:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:382:34: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:388:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:389:36: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:399:52: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:402:52: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:403:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:410:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:410:9: W292 no newline at end of file ./tests/conftest.py:11:1: E302 expected 2 blank lines, found 1 ./tests/conftest.py:42:63: E231 missing whitespace after ',' ./tests/conftest.py:56:49: E231 missing whitespace after ',' @@ -850,363 +952,691 @@ ./tests/conftest.py:125:28: E231 missing whitespace after ',' ./tests/conftest.py:127:19: E231 missing whitespace after ',' ./tests/conftest.py:129:21: W292 no newline at end of file -./tests/linkage/experiment/test_titrator.py:1:1: F401 'pytest' imported but unused -./tests/linkage/experiment/test_titrator.py:9:1: E302 expected 2 blank lines, found 1 -./tests/linkage/experiment/test_titrator.py:10:1: W293 blank line contains whitespace -./tests/linkage/experiment/test_titrator.py:11:35: E231 missing whitespace after ':' -./tests/linkage/experiment/test_titrator.py:11:40: E231 missing whitespace after ':' -./tests/linkage/experiment/test_titrator.py:11:42: E231 missing whitespace after ',' -./tests/linkage/experiment/test_titrator.py:11:46: E231 missing whitespace after ':' -./tests/linkage/experiment/test_titrator.py:12:38: E231 missing whitespace after ':' -./tests/linkage/experiment/test_titrator.py:12:43: E231 missing whitespace after ':' -./tests/linkage/experiment/test_titrator.py:12:46: E231 missing whitespace after ',' -./tests/linkage/experiment/test_titrator.py:12:50: E231 missing whitespace after ':' -./tests/linkage/experiment/test_titrator.py:13:33: E231 missing whitespace after ':' -./tests/linkage/experiment/test_titrator.py:14:37: E231 missing whitespace after ':' -./tests/linkage/experiment/test_titrator.py:14:48: E231 missing whitespace after ',' -./tests/linkage/experiment/test_titrator.py:15:37: E231 missing whitespace after ':' -./tests/linkage/experiment/test_titrator.py:16:1: W293 blank line contains whitespace -./tests/linkage/experiment/test_titrator.py:19:31: E231 missing whitespace after ',' -./tests/linkage/experiment/test_titrator.py:21:1: W391 blank line at end of file -./tests/linkage/models/test_base.py:14:1: E302 expected 2 blank lines, found 1 -./tests/linkage/models/test_base.py:17:33: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:17:38: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:20:33: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:20:38: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:23:33: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:23:38: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:23:42: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:26:33: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:26:38: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:26:42: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:30:33: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:30:38: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:30:42: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:30:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:30:50: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:47:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:51:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:53:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:57:32: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:57:37: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:58:31: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:58:36: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:63:32: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:63:37: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:64:31: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:64:36: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:105:32: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:105:37: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:105:41: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:105:45: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:106:31: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:106:36: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:106:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:110:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:114:32: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:114:38: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:114:43: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:115:33: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:115:36: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_experimental_point.py:6:1: E302 expected 2 blank lines, found 1 +./tests/linkage/experiment/point/test_experimental_point.py:21:1: W293 blank line contains whitespace +./tests/linkage/experiment/point/test_experimental_point.py:29:1: W293 blank line contains whitespace +./tests/linkage/experiment/point/test_itc_point.py:6:1: E302 expected 2 blank lines, found 1 +./tests/linkage/experiment/point/test_itc_point.py:13:30: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:13:34: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:14:30: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:14:33: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:15:38: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:15:41: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:19:26: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:20:21: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:21:21: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:24:26: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:37:1: W293 blank line contains whitespace +./tests/linkage/experiment/point/test_itc_point.py:43:1: W293 blank line contains whitespace +./tests/linkage/experiment/point/test_itc_point.py:50:76: W291 trailing whitespace +./tests/linkage/experiment/point/test_itc_point.py:51:15: W291 trailing whitespace +./tests/linkage/experiment/point/test_itc_point.py:59:1: E302 expected 2 blank lines, found 1 +./tests/linkage/experiment/point/test_itc_point.py:67:30: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:67:33: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:70:30: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:70:33: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:73:34: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:73:37: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:76:18: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:77:18: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:80:18: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:81:18: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:91:18: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:94:39: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:94:44: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:94:50: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:94:56: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:94:63: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:95:39: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:95:45: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:95:50: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:95:56: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:95:63: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:96:1: W293 blank line contains whitespace +./tests/linkage/experiment/point/test_itc_point.py:98:5: E303 too many blank lines (2) +./tests/linkage/experiment/point/test_itc_point.py:114:1: W293 blank line contains whitespace +./tests/linkage/experiment/point/test_itc_point.py:118:26: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:118:45: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:119:26: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:119:45: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:122:39: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_itc_point.py:125:1: W293 blank line contains whitespace +./tests/linkage/experiment/point/test_itc_point.py:129:1: W391 blank line at end of file +./tests/linkage/experiment/point/test_spec_point.py:6:1: E302 expected 2 blank lines, found 1 +./tests/linkage/experiment/point/test_spec_point.py:12:30: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:12:34: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:13:30: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:13:33: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:14:35: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:14:38: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:15:1: W293 blank line contains whitespace +./tests/linkage/experiment/point/test_spec_point.py:16:27: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:28:1: W293 blank line contains whitespace +./tests/linkage/experiment/point/test_spec_point.py:40:1: E302 expected 2 blank lines, found 1 +./tests/linkage/experiment/point/test_spec_point.py:43:5: E303 too many blank lines (2) +./tests/linkage/experiment/point/test_spec_point.py:46:30: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:46:34: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:47:30: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:47:33: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:48:35: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:48:38: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:49:1: W293 blank line contains whitespace +./tests/linkage/experiment/point/test_spec_point.py:51:18: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:52:18: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:55:18: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:56:18: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:59:27: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:73:1: W293 blank line contains whitespace +./tests/linkage/experiment/point/test_spec_point.py:75:1: W293 blank line contains whitespace +./tests/linkage/experiment/point/test_spec_point.py:77:5: E303 too many blank lines (2) +./tests/linkage/experiment/point/test_spec_point.py:85:1: W293 blank line contains whitespace +./tests/linkage/experiment/point/test_spec_point.py:87:1: W293 blank line contains whitespace +./tests/linkage/experiment/point/test_spec_point.py:89:5: E303 too many blank lines (2) +./tests/linkage/experiment/point/test_spec_point.py:90:18: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:91:18: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:93:27: E231 missing whitespace after ',' +./tests/linkage/experiment/point/test_spec_point.py:105:1: W293 blank line contains whitespace +./tests/linkage/experiment/point/test_spec_point.py:107:1: W293 blank line contains whitespace +./tests/linkage/experiment/point/test_spec_point.py:109:5: E303 too many blank lines (2) +./tests/linkage/experiment/point/test_spec_point.py:117:1: W293 blank line contains whitespace +./tests/linkage/experiment/point/test_spec_point.py:118:44: W292 no newline at end of file +./tests/linkage/experiment/test_experiment.py:13:1: E302 expected 2 blank lines, found 1 +./tests/linkage/experiment/test_experiment.py:18:18: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:18:21: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:18:23: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:22:12: E714 test for object identity should be 'is not' +./tests/linkage/experiment/test_experiment.py:22:28: E261 at least two spaces before inline comment +./tests/linkage/experiment/test_experiment.py:24:38: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:24:41: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:24:43: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:28:12: E714 test for object identity should be 'is not' +./tests/linkage/experiment/test_experiment.py:30:38: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:30:41: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:30:43: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:32:25: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:34:12: E714 test for object identity should be 'is not' +./tests/linkage/experiment/test_experiment.py:36:38: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:36:41: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:36:43: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:40:12: E714 test for object identity should be 'is not' +./tests/linkage/experiment/test_experiment.py:42:38: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:42:41: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:42:43: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:46:12: E714 test for object identity should be 'is not' +./tests/linkage/experiment/test_experiment.py:48:38: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:48:41: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:48:43: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:50:28: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:52:12: E714 test for object identity should be 'is not' +./tests/linkage/experiment/test_experiment.py:54:38: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:54:41: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:54:43: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:63:5: E303 too many blank lines (2) +./tests/linkage/experiment/test_experiment.py:68:35: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:68:38: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:68:40: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:70:41: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:70:54: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:72:29: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:72:32: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:72:34: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:76:35: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:76:38: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:77:38: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:77:45: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:80:41: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:80:54: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:81:46: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:81:49: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:81:51: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:82:49: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:82:55: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:82:61: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:82:69: W291 trailing whitespace +./tests/linkage/experiment/test_experiment.py:85:5: E303 too many blank lines (2) +./tests/linkage/experiment/test_experiment.py:85:35: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:85:38: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:86:38: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:86:45: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:87:29: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:87:32: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:90:41: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:90:54: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:90:69: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:91:46: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:91:49: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:91:51: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:92:49: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:92:55: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:92:61: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:92:69: W291 trailing whitespace +./tests/linkage/experiment/test_experiment.py:93:40: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:93:48: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:93:50: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:93:53: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:93:69: W291 trailing whitespace +./tests/linkage/experiment/test_experiment.py:98:42: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:98:45: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:98:47: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:99:25: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:100:28: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:111:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:112:41: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:117:42: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:118:48: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:118:61: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:118:70: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:118:90: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:118:94: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:120:43: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:131:50: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:131:55: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:131:59: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:139:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:141:50: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:141:55: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:141:59: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:145:21: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:146:21: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:147:21: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:148:21: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:149:21: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:150:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:151:1: E302 expected 2 blank lines, found 1 +./tests/linkage/experiment/test_experiment.py:153:42: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:153:45: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:153:47: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:154:36: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:154:39: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:154:41: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:155:25: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:156:28: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:167:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:173:70: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:175:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:189:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:203:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:217:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:231:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:233:5: E303 too many blank lines (2) +./tests/linkage/experiment/test_experiment.py:240:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:246:70: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:250:5: E303 too many blank lines (2) +./tests/linkage/experiment/test_experiment.py:263:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:265:5: E303 too many blank lines (2) +./tests/linkage/experiment/test_experiment.py:272:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:294:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:298:42: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:298:45: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:298:47: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:299:25: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:300:28: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:311:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:314:39: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:314:48: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:314:68: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:314:72: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:314:76: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:315:54: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:317:45: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:317:69: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:317:71: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:319:39: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:319:48: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:319:68: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:319:72: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:319:76: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:319:89: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:320:48: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:320:51: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:320:53: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:322:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:322:5: W292 no newline at end of file +./tests/linkage/experiment/test_titrator.py:12:1: E302 expected 2 blank lines, found 1 +./tests/linkage/experiment/test_titrator.py:13:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_titrator.py:14:35: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:14:40: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:14:42: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:14:46: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:15:38: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:15:43: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:15:46: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:15:50: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:16:33: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:17:37: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:17:48: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:18:37: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:19:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_titrator.py:22:31: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:24:46: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:24:64: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:29:31: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:31:46: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:36:16: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:36:18: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:36:22: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:37:19: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:37:22: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:37:26: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:41:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_titrator.py:42:34: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:42:39: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:42:43: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:55:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_titrator.py:59:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_titrator.py:63:16: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:63:18: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:63:22: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:63:24: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:63:28: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:64:19: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:64:22: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:64:26: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:64:28: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:64:32: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:65:32: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:83:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_titrator.py:84:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_titrator.py:85:5: E303 too many blank lines (2) +./tests/linkage/experiment/test_titrator.py:85:43: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:86:40: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:86:45: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:86:49: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:87:51: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:87:54: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:87:56: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:100:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_titrator.py:104:16: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:104:18: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:104:22: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:104:24: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:104:28: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:105:19: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:105:22: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:105:26: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:105:28: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:105:32: E231 missing whitespace after ':' +./tests/linkage/experiment/test_titrator.py:106:32: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:124:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_titrator.py:125:43: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:126:40: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:126:45: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:126:49: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:127:51: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:127:54: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:127:62: E231 missing whitespace after ',' +./tests/linkage/experiment/test_titrator.py:128:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_titrator.py:130:5: E303 too many blank lines (2) +./tests/linkage/experiment/test_titrator.py:134:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_titrator.py:139:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_titrator.py:145:1: W391 blank line at end of file +./tests/linkage/models/test_base.py:15:1: E302 expected 2 blank lines, found 1 +./tests/linkage/models/test_base.py:18:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:18:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:21:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:21:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:24:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:24:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:24:42: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:27:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:27:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:27:42: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:31:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:31:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:31:42: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:31:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:31:50: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:48:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:52:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:54:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:58:32: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:58:37: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:59:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:59:36: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:64:32: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:64:37: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:65:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:65:36: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:106:32: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:106:37: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:106:41: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:106:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:107:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:107:36: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:107:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:111:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:115:32: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:115:38: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:120:32: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:120:38: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:120:43: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:121:33: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:121:36: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:115:43: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:116:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:116:36: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:116:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:121:32: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:121:38: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:126:32: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:126:38: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:126:43: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:127:33: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:127:36: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:121:43: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:122:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:122:36: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:122:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:127:32: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:127:38: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:159:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:160:23: E231 missing whitespace after ':' -./tests/linkage/models/test_base.py:160:29: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:160:34: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:160:39: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:161:20: E231 missing whitespace after ':' -./tests/linkage/models/test_base.py:161:26: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:161:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:127:43: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:128:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:128:36: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:128:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:160:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:161:23: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:161:29: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:161:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:161:39: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:162:20: E231 missing whitespace after ':' ./tests/linkage/models/test_base.py:162:26: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:162:31: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:162:34: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:165:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:165:45: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:165:49: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:165:53: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:168:23: E231 missing whitespace after ':' -./tests/linkage/models/test_base.py:168:29: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:168:34: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:168:39: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:169:20: E231 missing whitespace after ':' -./tests/linkage/models/test_base.py:169:26: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:169:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:163:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:163:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:163:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:163:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:166:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:166:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:166:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:166:53: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:169:23: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:169:29: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:169:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:169:39: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:170:20: E231 missing whitespace after ':' ./tests/linkage/models/test_base.py:170:26: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:170:31: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:170:34: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:173:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:173:45: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:173:49: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:173:53: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:176:23: E231 missing whitespace after ':' -./tests/linkage/models/test_base.py:176:29: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:176:34: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:176:39: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:176:43: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:177:20: E231 missing whitespace after ':' -./tests/linkage/models/test_base.py:177:26: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:177:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:171:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:171:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:171:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:171:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:174:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:174:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:174:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:174:53: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:177:23: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:177:29: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:177:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:177:39: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:177:43: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:178:20: E231 missing whitespace after ':' ./tests/linkage/models/test_base.py:178:26: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:178:31: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:178:34: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:181:45: E128 continuation line under-indented for visual indent -./tests/linkage/models/test_base.py:182:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:184:23: E231 missing whitespace after ':' -./tests/linkage/models/test_base.py:184:29: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:184:33: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:184:38: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:184:43: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:185:20: E231 missing whitespace after ':' -./tests/linkage/models/test_base.py:185:26: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:185:31: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:185:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:179:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:179:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:179:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:179:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:182:45: E128 continuation line under-indented for visual indent +./tests/linkage/models/test_base.py:183:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:185:23: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:185:29: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:185:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:185:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:185:43: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:186:20: E231 missing whitespace after ':' ./tests/linkage/models/test_base.py:186:26: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:186:31: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:186:34: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:189:45: E128 continuation line under-indented for visual indent -./tests/linkage/models/test_base.py:190:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:192:23: E231 missing whitespace after ':' -./tests/linkage/models/test_base.py:192:29: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:192:34: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:192:39: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:192:43: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:193:20: E231 missing whitespace after ':' -./tests/linkage/models/test_base.py:193:26: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:193:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:187:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:187:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:187:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:187:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:190:45: E128 continuation line under-indented for visual indent +./tests/linkage/models/test_base.py:191:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:193:23: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:193:29: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:193:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:193:39: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:193:43: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:194:20: E231 missing whitespace after ':' ./tests/linkage/models/test_base.py:194:26: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:194:30: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:194:35: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:194:38: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:197:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:197:45: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:197:49: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:197:53: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:197:57: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:200:23: E231 missing whitespace after ':' -./tests/linkage/models/test_base.py:200:29: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:200:34: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:200:39: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:201:20: E231 missing whitespace after ':' -./tests/linkage/models/test_base.py:201:26: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:201:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:194:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:194:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:195:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:195:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:195:30: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:195:35: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:195:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:198:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:198:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:198:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:198:53: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:198:57: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:201:23: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:201:29: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:201:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:201:39: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:202:20: E231 missing whitespace after ':' ./tests/linkage/models/test_base.py:202:26: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:202:30: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:202:35: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:202:38: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:205:45: E128 continuation line under-indented for visual indent -./tests/linkage/models/test_base.py:206:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:209:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:210:20: E231 missing whitespace after ':' -./tests/linkage/models/test_base.py:210:26: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:210:31: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:210:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:202:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:202:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:203:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:203:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:203:30: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:203:35: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:203:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:206:45: E128 continuation line under-indented for visual indent +./tests/linkage/models/test_base.py:207:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:210:1: W293 blank line contains whitespace ./tests/linkage/models/test_base.py:211:20: E231 missing whitespace after ':' ./tests/linkage/models/test_base.py:211:26: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:211:31: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:211:34: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:212:25: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:212:29: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:212:33: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:216:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:218:44: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:218:50: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:218:53: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:218:58: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:212:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:212:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:212:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:212:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:213:25: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:213:29: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:213:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:217:1: W293 blank line contains whitespace ./tests/linkage/models/test_base.py:219:44: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:219:50: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:219:53: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:219:58: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:220:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:220:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:222:20: E231 missing whitespace after ':' -./tests/linkage/models/test_base.py:222:26: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:222:31: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:222:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:220:44: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:220:50: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:220:53: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:220:58: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:221:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:221:46: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:223:20: E231 missing whitespace after ':' ./tests/linkage/models/test_base.py:223:26: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:223:31: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:223:35: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:224:25: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:224:29: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:224:33: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:228:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:230:44: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:230:50: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:230:53: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:230:58: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:223:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:224:20: E231 missing whitespace after ':' +./tests/linkage/models/test_base.py:224:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:224:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:224:35: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:225:25: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:225:29: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:225:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:229:1: W293 blank line contains whitespace ./tests/linkage/models/test_base.py:231:44: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:231:50: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:231:54: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:231:59: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:232:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:232:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:235:5: E303 too many blank lines (2) -./tests/linkage/models/test_base.py:235:20: E231 missing whitespace after ':' -./tests/linkage/models/test_base.py:235:26: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:235:30: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:235:36: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:235:39: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:235:41: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:231:53: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:231:58: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:232:44: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:232:50: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:232:54: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:232:59: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:233:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:233:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:236:5: E303 too many blank lines (2) ./tests/linkage/models/test_base.py:236:20: E231 missing whitespace after ':' ./tests/linkage/models/test_base.py:236:26: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:236:31: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:236:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:236:30: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:236:36: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:236:39: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:236:41: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:237:20: E231 missing whitespace after ':' ./tests/linkage/models/test_base.py:237:26: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:237:30: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:237:31: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:237:34: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:237:38: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:239:40: W291 trailing whitespace -./tests/linkage/models/test_base.py:242:57: E127 continuation line over-indented for visual indent -./tests/linkage/models/test_base.py:248:5: E122 continuation line missing indentation or outdented -./tests/linkage/models/test_base.py:251:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:258:50: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:259:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:259:51: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:259:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:238:26: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:238:30: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:238:34: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:238:38: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:240:40: W291 trailing whitespace +./tests/linkage/models/test_base.py:243:57: E127 continuation line over-indented for visual indent +./tests/linkage/models/test_base.py:249:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:252:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:259:50: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:260:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:263:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:263:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:260:51: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:260:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:261:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:264:40: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:264:46: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:265:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:266:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:266:45: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:266:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:266:46: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:267:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:271:5: E122 continuation line missing indentation or outdented -./tests/linkage/models/test_base.py:274:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:284:5: E122 continuation line missing indentation or outdented -./tests/linkage/models/test_base.py:287:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:297:5: E122 continuation line missing indentation or outdented -./tests/linkage/models/test_base.py:300:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:310:5: E122 continuation line missing indentation or outdented -./tests/linkage/models/test_base.py:313:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:323:5: E122 continuation line missing indentation or outdented -./tests/linkage/models/test_base.py:326:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:334:6: E114 indentation is not a multiple of 4 (comment) -./tests/linkage/models/test_base.py:336:5: E122 continuation line missing indentation or outdented -./tests/linkage/models/test_base.py:339:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:347:6: E114 indentation is not a multiple of 4 (comment) -./tests/linkage/models/test_base.py:349:5: E122 continuation line missing indentation or outdented -./tests/linkage/models/test_base.py:352:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:360:6: E114 indentation is not a multiple of 4 (comment) -./tests/linkage/models/test_base.py:360:30: W291 trailing whitespace -./tests/linkage/models/test_base.py:362:5: E122 continuation line missing indentation or outdented -./tests/linkage/models/test_base.py:365:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:371:50: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:372:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:372:51: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:372:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:267:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:267:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:268:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:272:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:275:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:285:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:288:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:298:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:301:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:311:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:314:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:324:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:327:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:335:6: E114 indentation is not a multiple of 4 (comment) +./tests/linkage/models/test_base.py:337:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:340:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:348:6: E114 indentation is not a multiple of 4 (comment) +./tests/linkage/models/test_base.py:350:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:353:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:361:6: E114 indentation is not a multiple of 4 (comment) +./tests/linkage/models/test_base.py:361:30: W291 trailing whitespace +./tests/linkage/models/test_base.py:363:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:366:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:372:50: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:373:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:376:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:376:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:373:51: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:373:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:374:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:377:40: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:377:46: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:378:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:379:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:379:45: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:379:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:379:46: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:380:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:384:5: E122 continuation line missing indentation or outdented -./tests/linkage/models/test_base.py:387:6: W291 trailing whitespace -./tests/linkage/models/test_base.py:393:50: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:394:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:394:51: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:394:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:380:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:380:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:381:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:385:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:388:6: W291 trailing whitespace +./tests/linkage/models/test_base.py:394:50: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:395:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:398:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:398:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:395:51: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:395:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:396:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:399:40: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:399:46: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:400:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:401:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:401:45: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:401:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:401:46: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:402:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:404:7: E114 indentation is not a multiple of 4 (comment) -./tests/linkage/models/test_base.py:404:7: E116 unexpected indentation (comment) -./tests/linkage/models/test_base.py:406:5: E122 continuation line missing indentation or outdented -./tests/linkage/models/test_base.py:410:6: W291 trailing whitespace -./tests/linkage/models/test_base.py:418:50: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:419:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:419:51: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:419:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:402:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:402:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:403:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:405:7: E114 indentation is not a multiple of 4 (comment) +./tests/linkage/models/test_base.py:405:7: E116 unexpected indentation (comment) +./tests/linkage/models/test_base.py:407:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:411:6: W291 trailing whitespace +./tests/linkage/models/test_base.py:419:50: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:420:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:423:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:423:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:420:51: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:420:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:421:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:424:40: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:424:46: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:425:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:426:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:426:45: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:426:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:426:46: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:427:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:431:5: E122 continuation line missing indentation or outdented -./tests/linkage/models/test_base.py:435:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:445:5: E122 continuation line missing indentation or outdented -./tests/linkage/models/test_base.py:449:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:457:31: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:457:37: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:458:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:458:51: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:458:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:427:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:427:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:428:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:432:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:436:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:446:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:450:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:458:31: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:458:37: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:459:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:459:51: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:459:55: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:460:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:460:51: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:460:55: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:461:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:464:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:464:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:461:51: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:461:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:462:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:465:40: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:465:46: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:466:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:467:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:467:45: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:467:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:467:46: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:468:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:472:5: E122 continuation line missing indentation or outdented -./tests/linkage/models/test_base.py:475:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:484:5: E266 too many leading '#' for block comment -./tests/linkage/models/test_base.py:486:5: E122 continuation line missing indentation or outdented -./tests/linkage/models/test_base.py:489:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:497:50: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:498:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:498:51: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:498:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:468:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:468:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:469:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:473:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:476:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:485:5: E266 too many leading '#' for block comment +./tests/linkage/models/test_base.py:487:5: E122 continuation line missing indentation or outdented +./tests/linkage/models/test_base.py:490:1: W293 blank line contains whitespace +./tests/linkage/models/test_base.py:498:50: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:499:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:504:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:504:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:499:51: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:499:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:500:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:505:40: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:505:46: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:506:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:508:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:508:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:507:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:509:40: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:509:46: E231 missing whitespace after ',' ./tests/linkage/models/test_base.py:510:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:511:1: W293 blank line contains whitespace -./tests/linkage/models/test_base.py:512:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:512:45: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:512:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:511:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:512:1: W293 blank line contains whitespace ./tests/linkage/models/test_base.py:513:40: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:513:46: E231 missing whitespace after ',' -./tests/linkage/models/test_base.py:513:53: W292 no newline at end of file +./tests/linkage/models/test_base.py:513:45: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:513:49: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:514:40: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:514:46: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:520:25: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:520:29: W291 trailing whitespace +./tests/linkage/models/test_base.py:527:25: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:527:29: W291 trailing whitespace +./tests/linkage/models/test_base.py:535:27: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:543:25: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:543:30: W291 trailing whitespace +./tests/linkage/models/test_base.py:551:25: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:551:28: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:551:30: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:551:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:551:40: W291 trailing whitespace +./tests/linkage/models/test_base.py:554:55: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:558:25: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:558:28: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:558:30: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:558:33: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:558:40: W291 trailing whitespace +./tests/linkage/models/test_base.py:561:41: E128 continuation line under-indented for visual indent +./tests/linkage/models/test_base.py:562:41: E128 continuation line under-indented for visual indent +./tests/linkage/models/test_base.py:562:57: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:566:25: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:566:28: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:566:30: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:566:37: W291 trailing whitespace +./tests/linkage/models/test_base.py:572:25: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:572:28: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:572:30: E231 missing whitespace after ',' +./tests/linkage/models/test_base.py:572:42: W291 trailing whitespace ./tests/linkage/models/test_ca_edta.py:7:1: E302 expected 2 blank lines, found 1 ./tests/linkage/models/test_ca_edta.py:9:27: E231 missing whitespace after ',' ./tests/linkage/models/test_ca_edta.py:9:39: E231 missing whitespace after ',' @@ -1300,43 +1730,57 @@ ./tests/linkage/organizer/test_global_model.py:112:23: E231 missing whitespace after ',' ./tests/linkage/organizer/test_global_model.py:112:30: E231 missing whitespace after ',' ./tests/linkage/organizer/test_global_model.py:112:37: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:113:25: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:113:34: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:113:43: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:113:52: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:116:35: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:126:1: E302 expected 2 blank lines, found 1 -./tests/linkage/organizer/test_global_model.py:139:1: E302 expected 2 blank lines, found 1 -./tests/linkage/organizer/test_global_model.py:141:59: W291 trailing whitespace -./tests/linkage/organizer/test_global_model.py:143:51: W291 trailing whitespace -./tests/linkage/organizer/test_global_model.py:146:1: W293 blank line contains whitespace -./tests/linkage/organizer/test_global_model.py:161:1: W293 blank line contains whitespace -./tests/linkage/organizer/test_global_model.py:162:5: E303 too many blank lines (2) -./tests/linkage/organizer/test_global_model.py:162:39: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:163:38: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:165:46: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:165:56: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:173:5: E303 too many blank lines (2) -./tests/linkage/organizer/test_global_model.py:177:22: E128 continuation line under-indented for visual indent -./tests/linkage/organizer/test_global_model.py:177:47: W292 no newline at end of file -4 C901 'titrator' is too complex (11) +./tests/linkage/organizer/test_global_model.py:112:44: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:112:51: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:112:58: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:112:67: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:112:76: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:114:35: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:115:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:117:33: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:117:35: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:117:37: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:117:39: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:117:41: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:122:38: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:122:48: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:125:27: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:128:5: E303 too many blank lines (2) +./tests/linkage/organizer/test_global_model.py:138:1: E302 expected 2 blank lines, found 1 +./tests/linkage/organizer/test_global_model.py:151:1: E302 expected 2 blank lines, found 1 +./tests/linkage/organizer/test_global_model.py:153:59: W291 trailing whitespace +./tests/linkage/organizer/test_global_model.py:155:51: W291 trailing whitespace +./tests/linkage/organizer/test_global_model.py:158:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:173:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:174:5: E303 too many blank lines (2) +./tests/linkage/organizer/test_global_model.py:174:39: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:175:38: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:177:46: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:177:56: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:185:5: E303 too many blank lines (2) +./tests/linkage/organizer/test_global_model.py:189:22: E128 continuation line under-indented for visual indent +./tests/linkage/organizer/test_global_model.py:189:47: W292 no newline at end of file +2 C901 '_parse_linkage_docstring' is too complex (14) 4 E114 indentation is not a multiple of 4 (comment) 1 E116 unexpected indentation (comment) 15 E122 continuation line missing indentation or outdented 6 E127 continuation line over-indented for visual indent -11 E128 continuation line under-indented for visual indent -12 E225 missing whitespace around operator -663 E231 missing whitespace after ',' +18 E128 continuation line under-indented for visual indent +4 E221 multiple spaces before operator +4 E225 missing whitespace around operator +933 E231 missing whitespace after ',' +1 E261 at least two spaces before inline comment 1 E266 too many leading '#' for block comment -39 E302 expected 2 blank lines, found 1 -22 E303 too many blank lines (3) +54 E302 expected 2 blank lines, found 1 +43 E303 too many blank lines (2) +6 E714 test for object identity should be 'is not' 2 E722 do not use bare 'except' 2 E741 ambiguous variable name 'I' -14 F401 'linkage.experiment.Experiment' imported but unused +15 F401 'linkage.experiment.Experiment' imported but unused 1 F541 f-string is missing placeholders 2 F841 local variable 'args' is assigned to but never used -156 W291 trailing whitespace -18 W292 no newline at end of file -345 W293 blank line contains whitespace -3 W391 blank line at end of file -1321 +203 W291 trailing whitespace +22 W292 no newline at end of file +410 W293 blank line contains whitespace +13 W391 blank line at end of file +1762 diff --git a/reports/junit/junit.xml b/reports/junit/junit.xml index 2195653..ff7c83b 100644 --- a/reports/junit/junit.xml +++ b/reports/junit/junit.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/linkage/experiment/point/experimental_point.py b/src/linkage/experiment/point/experimental_point.py index 3185323..3fc361f 100644 --- a/src/linkage/experiment/point/experimental_point.py +++ b/src/linkage/experiment/point/experimental_point.py @@ -11,7 +11,8 @@ def __init__(self, expt_idx, obs_key, micro_array, - macro_array): + macro_array, + del_macro_array): """ Should be sub-classed. """ @@ -21,6 +22,7 @@ def __init__(self, self._obs_key = obs_key self._micro_array = micro_array self._macro_array = macro_array + self._del_macro_array = del_macro_array @property def idx(self): diff --git a/src/linkage/experiment/point/itc_point.py b/src/linkage/experiment/point/itc_point.py index abee326..2009e7c 100644 --- a/src/linkage/experiment/point/itc_point.py +++ b/src/linkage/experiment/point/itc_point.py @@ -15,6 +15,7 @@ def __init__(self, obs_key, micro_array, macro_array, + del_macro_array, meas_vol_dilution, dh_param_start_idx, dh_param_end_idx, @@ -37,6 +38,9 @@ def __init__(self, macro_array : np.ndarray (float) array holding concentrations of all macroscopic species, calculated elsewhere + del_macro_array : np.ndarray (float) + array holding change in concentrations of all macroscopic species + from the syringe to this condition meas_vol_dilution : float how much this shot diluted the measurement volume of the cell. This is calculated using the "titrator" function and corresponds to @@ -57,14 +61,21 @@ def __init__(self, expt_idx=expt_idx, obs_key=obs_key, micro_array=micro_array, - macro_array=macro_array) + macro_array=macro_array, + del_macro_array=del_macro_array) self._meas_vol_dilution = meas_vol_dilution self._dh_param_start_idx = dh_param_start_idx self._dh_param_end_idx = dh_param_end_idx self._dh_sign = dh_sign self._dh_product_mask = dh_product_mask - + + # Decide how to cut parameter array into enthalpies (first block of + # param) and heats of dilution (second block of param) + self._dh_first = self._dh_param_start_idx + self._dh_last = self._dh_first + len(self._dh_sign) + self._dil_first = self._dh_last + self._dil_last = self._dh_param_end_idx def calc_value(self,parameters,*args,**kwargs): """ @@ -78,16 +89,19 @@ def calc_value(self,parameters,*args,**kwargs): fit parameters (guesses array) """ - dh_array = parameters[self._dh_param_start_idx:self._dh_param_end_idx] - + dh_array = parameters[self._dh_first:self._dh_last] + total_heat = 0.0 - for i in range(len(dh_array)): + for i in range(len(self._dh_product_mask)): C_after = self._micro_array[self._idx,self._dh_product_mask[i]] C_before = self._micro_array[self._idx-1,self._dh_product_mask[i]] dC = np.mean(C_after - C_before*self._meas_vol_dilution) total_heat += dh_array[i]*self._dh_sign[i]*dC - - + + # # Dilution correction + dil_array = parameters[self._dil_first:self._dil_last] + total_heat += np.sum(dil_array*self._del_macro_array[self._idx,:]) + return total_heat \ No newline at end of file diff --git a/src/linkage/experiment/point/spec_point.py b/src/linkage/experiment/point/spec_point.py index 6a35990..0264f42 100644 --- a/src/linkage/experiment/point/spec_point.py +++ b/src/linkage/experiment/point/spec_point.py @@ -15,6 +15,7 @@ def __init__(self, obs_key, micro_array, macro_array, + del_macro_array, obs_mask, denom): """ @@ -34,6 +35,9 @@ def __init__(self, macro_array : np.ndarray (float) array holding concentrations of all macroscopic species, calculated elsewhere + del_macro_array : np.ndarray (float) + array holding change in concentrations of all macroscopic species + from the syringe to this condition obs_mask : np.ndarray (bool or int) mask that grabs microscopic species from micro_array that correspond to the numerator when calculating the observable @@ -46,7 +50,8 @@ def __init__(self, expt_idx=expt_idx, obs_key=obs_key, micro_array=micro_array, - macro_array=macro_array) + macro_array=macro_array, + del_macro_array=del_macro_array) self._obs_mask = obs_mask self._denom = denom diff --git a/src/linkage/organizer/global_model.py b/src/linkage/organizer/global_model.py index f48841a..52d8912 100644 --- a/src/linkage/organizer/global_model.py +++ b/src/linkage/organizer/global_model.py @@ -149,8 +149,13 @@ def _get_enthalpy_param(self): self._all_parameter_names.append(f"dH_{s[1:]}") self._parameter_guesses.append(0.0) + # Heats of dilution + for k in self._bm.macro_species: + self._all_parameter_names.append(f"dil_{k}") + self._parameter_guesses.append(0.0) + # Last enthalpy index is last entry - self._dh_param_end_idx = len(self._all_parameter_names) - 1 + self._dh_param_end_idx = len(self._all_parameter_names) - 1 def _process_expt_fudge(self): @@ -178,6 +183,7 @@ def _build_point_map(self): # Lists of arrays that can be referenced by the individual points self._micro_arrays = [] self._macro_arrays = [] + self._del_macro_arrays = [] self._points = [] self._y_obs = [] @@ -194,6 +200,18 @@ def _build_point_map(self): macro_array = np.array(expt.expt_concs.loc[:,self._bm.macro_species], dtype=float) self._macro_arrays.append(macro_array) + + # ... and an array of holding change in macro species relative to + # syringe. + syringe_concs = [] + for s in self._bm.macro_species: + if s in expt.syringe_contents: + syringe_concs.append(expt.syringe_contents[s]) + else: + syringe_concs.append(0.0) + + del_macro_array = np.array(syringe_concs,dtype=float) - macro_array + self._del_macro_arrays.append(del_macro_array) for obs in expt.observables: @@ -215,6 +233,7 @@ def _build_point_map(self): obs_key=obs, micro_array=self._micro_arrays[-1], macro_array=self._macro_arrays[-1], + del_macro_array=self._del_macro_arrays[-1], obs_mask=np.isin(self._bm.micro_species, obs_info["observable_species"]), denom=den_index) @@ -229,6 +248,7 @@ def _build_point_map(self): obs_key=obs, micro_array=self._micro_arrays[-1], macro_array=self._macro_arrays[-1], + del_macro_array=self._del_macro_arrays[-1], meas_vol_dilution=meas_vol_dilution, dh_param_start_idx=self._dh_param_start_idx, dh_param_end_idx=self._dh_param_end_idx + 1, diff --git a/tests/linkage/experiment/point/test_experimental_point.py b/tests/linkage/experiment/point/test_experimental_point.py index 595baf1..c49ae90 100644 --- a/tests/linkage/experiment/point/test_experimental_point.py +++ b/tests/linkage/experiment/point/test_experimental_point.py @@ -11,11 +11,13 @@ def test_ExperimentalPoint(): obs_key = "test" micro_array = np.ones(10) macro_array = np.ones(3) + del_macro_array = np.zeros(3) e = ExperimentalPoint(idx=idx, expt_idx=expt_idx, obs_key=obs_key, micro_array=micro_array, - macro_array=macro_array) + macro_array=macro_array, + del_macro_array=del_macro_array) assert e.idx == 0 assert e.expt_idx == 1 @@ -23,4 +25,5 @@ def test_ExperimentalPoint(): assert e._micro_array is micro_array assert e._macro_array is macro_array + assert e._del_macro_array is del_macro_array diff --git a/tests/linkage/experiment/point/test_itc_point.py b/tests/linkage/experiment/point/test_itc_point.py index 3cbd9c3..359d3bb 100644 --- a/tests/linkage/experiment/point/test_itc_point.py +++ b/tests/linkage/experiment/point/test_itc_point.py @@ -12,9 +12,10 @@ def test_ITCPoint(): obs_key = "test" micro_array = np.ones((50,10),dtype=float) macro_array = np.ones((50,3),dtype=float) + del_macro_array = 0.1*np.ones((50,3),dtype=float) meas_vol_dilution = 1.0 dh_param_start_idx = 1 - dh_param_end_idx = 3 + dh_param_end_idx = 4 dh_sign = np.array([1,-1]) m0 = np.zeros(10,dtype=bool) m1 = np.zeros(10,dtype=bool) @@ -27,6 +28,7 @@ def test_ITCPoint(): obs_key=obs_key, micro_array=micro_array, macro_array=macro_array, + del_macro_array=del_macro_array, meas_vol_dilution=meas_vol_dilution, dh_param_start_idx=dh_param_start_idx, dh_param_end_idx=dh_param_end_idx, @@ -67,6 +69,9 @@ def test_ITCPoints_get_value(): # Make a micro array that has two rows and five microspecies micro_array = np.zeros((2,5),dtype=float) + # del macro array + del_macro_array = np.zeros((2,3),dtype=float) - 0.1 + # Species 1 changes from 1.0 -> 1.2 over this step micro_array[0,1] = 1.0 micro_array[1,1] = 1.2 @@ -80,7 +85,7 @@ def test_ITCPoints_get_value(): # Parameters in array are 3 and 4 dh_param_start_idx = 3 - dh_param_end_idx = 5 + dh_param_end_idx = 8 # negative and positive sign for dH dh_sign = [-1,1] @@ -100,6 +105,7 @@ def test_ITCPoints_get_value(): obs_key=obs_key, micro_array=micro_array, macro_array=macro_array, + del_macro_array=del_macro_array, meas_vol_dilution=meas_vol_dilution, dh_param_start_idx=dh_param_start_idx, dh_param_end_idx=dh_param_end_idx, diff --git a/tests/linkage/experiment/point/test_spec_point.py b/tests/linkage/experiment/point/test_spec_point.py index a91647a..1e00e0c 100644 --- a/tests/linkage/experiment/point/test_spec_point.py +++ b/tests/linkage/experiment/point/test_spec_point.py @@ -11,6 +11,7 @@ def test_SpecPoint(): obs_key = "test" micro_array = np.ones((50,10),dtype=float) macro_array = np.ones((50,3),dtype=float) + del_macro_array = np.zeros((50,3),dtype=float) obs_mask = np.zeros(10,dtype=bool) obs_mask[1] = True @@ -21,6 +22,7 @@ def test_SpecPoint(): obs_key=obs_key, micro_array=micro_array, macro_array=macro_array, + del_macro_array=del_macro_array, obs_mask=obs_mask, denom=denom) @@ -30,6 +32,7 @@ def test_SpecPoint(): assert e._micro_array is micro_array assert e._macro_array is macro_array + assert e._del_macro_array is del_macro_array assert e._obs_mask is obs_mask assert e._denom == denom @@ -37,12 +40,12 @@ def test_SpecPoint(): def test_SpecPoint_calc_value(): - idx = 0 expt_idx = 1 obs_key = "test" micro_array = np.ones((50,10),dtype=float) macro_array = np.ones((50,3),dtype=float) + del_macro_array = np.zeros((50,3),dtype=float) # Point 0 and 1 in micro array micro_array[0,1] = 50 @@ -64,6 +67,7 @@ def test_SpecPoint_calc_value(): obs_key=obs_key, micro_array=micro_array, macro_array=macro_array, + del_macro_array=del_macro_array, obs_mask=obs_mask, denom=denom) @@ -75,6 +79,7 @@ def test_SpecPoint_calc_value(): obs_key=obs_key, micro_array=micro_array, macro_array=macro_array, + del_macro_array=del_macro_array, obs_mask=obs_mask, denom=denom) @@ -94,6 +99,7 @@ def test_SpecPoint_calc_value(): obs_key=obs_key, micro_array=micro_array, macro_array=macro_array, + del_macro_array=del_macro_array, obs_mask=obs_mask, denom=denom) @@ -105,6 +111,7 @@ def test_SpecPoint_calc_value(): obs_key=obs_key, micro_array=micro_array, macro_array=macro_array, + del_macro_array=del_macro_array, obs_mask=obs_mask, denom=denom) diff --git a/tests/linkage/organizer/test_global_model.py b/tests/linkage/organizer/test_global_model.py index 1cc22e9..cd180db 100644 --- a/tests/linkage/organizer/test_global_model.py +++ b/tests/linkage/organizer/test_global_model.py @@ -109,7 +109,7 @@ def test_GlobalModel__get_enthalpy_param(fake_spec_and_itc_data): assert gf._dh_param_start_idx is not None assert gf._dh_param_end_idx is not None - expected = ['dH_I','dH_E','dH_1','dH_2','dH_3','dH_4'] + expected = ['dH_I','dH_E','dH_1','dH_2','dH_3','dH_4',"dil_AT","dil_CT","dil_ET"] dh_param = gf._all_parameter_names[gf._dh_param_start_idx:gf._dh_param_end_idx + 1] assert np.array_equal(expected,dh_param) @@ -118,7 +118,7 @@ def test_GlobalModel__get_enthalpy_param(fake_spec_and_itc_data): # make sure it is correctly mapping reactions assert gf._dh_param_start_idx == 6 - assert gf._dh_param_end_idx == 11 + assert gf._dh_param_end_idx == 14 assert np.array_equal(gf._dh_sign,np.ones(6,dtype=float)) for i in range(6): assert np.sum(gf._dh_product_mask[i]) == 1 From a6dc4faaaedcfd8ee705b8363a7973125b723ba4 Mon Sep 17 00:00:00 2001 From: Michael Harms Date: Tue, 30 Jul 2024 09:47:52 -0700 Subject: [PATCH 11/17] added openpyxl dependency for better excel reading --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 29b2480..143ca2d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,7 @@ dependencies = [ "numpy", "pandas", "matplotlib", + "openpyxl", "dataprob" ] From e4731038d61b99d592d1075f9d225c138bbd205b Mon Sep 17 00:00:00 2001 From: Michael Harms Date: Tue, 30 Jul 2024 15:42:50 -0700 Subject: [PATCH 12/17] experiment observable now enforces need for stdev --- src/linkage/experiment/experiment.py | 175 +++++++++--- src/linkage/experiment/point/itc_point.py | 16 +- src/linkage/organizer/global_model.py | 280 +++++++++++++++---- tests/conftest.py | 21 +- tests/linkage/experiment/test_experiment.py | 215 ++++++++------ tests/linkage/organizer/test_global_model.py | 96 ++++++- 6 files changed, 609 insertions(+), 194 deletions(-) diff --git a/src/linkage/experiment/experiment.py b/src/linkage/experiment/experiment.py index f7d5053..dd71b55 100644 --- a/src/linkage/experiment/experiment.py +++ b/src/linkage/experiment/experiment.py @@ -5,6 +5,7 @@ import pandas as pd import copy +import warnings def _load_dataframe(expt_data): @@ -66,9 +67,37 @@ def __init__(self, expt_data, cell_contents, syringe_contents, + cell_volume, conc_to_float=None, - cell_volume=1800, constant_volume=False): + """ + Load an experimental dataset. + + Parameters + ---------- + expt_data : str or pandas.DataFrame + DataFrame with experimental data. If passed in as a string, try to + read from file. Otherwise, use as dataframe. DataFrame must have + an 'injection' column holding injection volumes for experiments. + cell_contents : dict + dictionary keying macrospecies from the binding model to their + concentrations in the cell prior to any injection + syringe_contents : dict + dictionary keying macrospecies from the binding model to their + concentrations in the syringe. + cell_volume : float + volume of the cell into which the titration is done. the units of + this volume should match the units of the 'injection' column. + conc_to_float : str, optional + name of the most macrospecies with the most uncertain concentration + in the experiment (usually a macromolecule). If specified, this + concentration will be allowed to float in the fit (look for a + "fudge" parameter). + constant_volume : bool, default=False + if True, an injection with volume X uL is treated as "suck out X uL + and send to waste, then add X uL from syringe." if False, each + injection increases the total volume. + """ # Process and clean up input experimental data expt_data = _load_dataframe(expt_data=expt_data) @@ -95,51 +124,125 @@ def __init__(self, self._conc_to_float = conc_to_float self._observables = {} - - def add_observable(self, - column_name, - obs_type, - observable_species=None, - denominator=None): - if column_name not in self._expt_data: + def _define_generic_observable(self, + obs_column, + obs_stdev): + """ + Define observable, making sure obs_column and obs_stdev columns are + sane. If obs_stdev is a float, make a new column named {obs_column}_stdev + with the value loaded in. + """ + + if obs_column not in self._expt_data.columns: err = "column_name should be one of the columns in the experimental data\n" raise ValueError(err) - if column_name == "injection": + if obs_column == "injection": err = "column_name cannot be injection\n" raise ValueError(err) - - if obs_type not in ["spec","itc"]: - err = "obs_type should be 'spec' or 'itc'\n" - raise ValueError(err) - - if obs_type == "spec": + + # Deal with uncertainty + if obs_stdev in self._expt_data.columns: + obs_stdev_column = obs_stdev + else: + obs_stdev_column = f"{obs_column}_stdev" - if observable_species is None: - err = "observable_species must be specified for a 'spec' experiment\n" - raise ValueError(err) - - if issubclass(type(observable_species),str): - observable_species = [observable_species] - - if not hasattr(observable_species,'__iter__'): - err = "observable_species should be a list of species contributing to signal\n" - raise ValueError(err) + try: + obs_stdev = float(obs_stdev) + except Exception as e: + err = "obs_stdev should be either the name of a column or a single value\n" + raise ValueError(err) from e - if denominator is None: - err = "denominator must be specified for a 'spec' experiment.\n" - raise ValueError(err) + self._expt_data.loc[:,obs_stdev_column] = obs_stdev + + if obs_column in self._observables: + w = f"obs_column '{obs_column}' was already adding. Overwriting\n" + warnings.warn(w) + + + return obs_column, obs_stdev_column + + def define_itc_observable(self, + obs_column, + obs_stdev): + """ + Define an ITC observable for this experiment. + + Parameters + ---------- + obs_column : str + name of column in initial dataframe that has the experimental + observable. + obs_stdev : str or float, optional + If str, use as name of column in initial dataframe that has the + standard deviation on each observation. If float, use this single + value as the standard deviation on all observations. + """ + + obs_column, obs_stdev_column = self._define_generic_observable(obs_column=obs_column, + obs_stdev=obs_stdev) + + self._observables[obs_column] = {"type":"itc", + "stdev_column":obs_stdev_column} + + + def define_spectroscopic_observable(self, + obs_column, + obs_stdev, + obs_microspecies, + obs_macrospecies): + """ + Define a spectroscopic observable for this experiment. + + Parameters + ---------- + obs_column : str + name of column in initial dataframe that has the experimental + observable. + obs_stdev : str or float, optional + If str, use as name of column in initial dataframe that has the + standard deviation on each observation. If float, use this single + value as the standard deviation on all observations. + obs_microspecies : list-like + list of microscopic species from binding model that contribute to + this spectroscopic signal. + obs_macrospecies: str + name of the macroscopic species from the binding model to use as the + denominator for the observable. (This must be somewhere in the + cell_contents or syringe_contents dictionaries as well.) + + Example + ------- + Consider the binding reaction where the spectroscopic signal of "A" + changes when "B" binds: + + AT = A + AB + BT = B + AB + + obs_microspecies would be ["AB"] and obs_macrospecies would be "AT". + """ + + obs_column, obs_stdev_column = self._define_generic_observable(obs_column=obs_column, + obs_stdev=obs_stdev) + + if issubclass(type(obs_microspecies),str): + obs_microspecies = [obs_microspecies] + + if not hasattr(obs_microspecies,'__iter__'): + err = "obs_microspecies should be a list of species contributing to signal\n" + raise ValueError(err) - macrospecies = self._expt_concs.columns - macrospecies = [m for m in macrospecies if m != "injection"] - if denominator not in macrospecies: - err = f"denominator must be one of: {','.join(macrospecies)}\n" - raise ValueError(err) + expt_macrospecies = self._expt_concs.columns + expt_macrospecies = [m for m in expt_macrospecies if m != "injection"] + if obs_macrospecies not in expt_macrospecies: + err = f"obs_macrospecies must be one of: {','.join(expt_macrospecies)}\n" + raise ValueError(err) - self._observables[column_name] = {"obs_type":obs_type, - "observable_species":observable_species, - "denominator":denominator} + self._observables[obs_column] = {"type":"spec", + "stdev_column":obs_stdev_column, + "microspecies":obs_microspecies, + "macrospecies":obs_macrospecies} def add_expt_conc_column(self,new_column,conc_vector=None): diff --git a/src/linkage/experiment/point/itc_point.py b/src/linkage/experiment/point/itc_point.py index 2009e7c..a013422 100644 --- a/src/linkage/experiment/point/itc_point.py +++ b/src/linkage/experiment/point/itc_point.py @@ -94,9 +94,21 @@ def calc_value(self,parameters,*args,**kwargs): total_heat = 0.0 for i in range(len(self._dh_product_mask)): - C_after = self._micro_array[self._idx,self._dh_product_mask[i]] + # Concentration of relevant microspecies before the injection C_before = self._micro_array[self._idx-1,self._dh_product_mask[i]] - dC = np.mean(C_after - C_before*self._meas_vol_dilution) + + # Concentration of relevant microspecies after the injection + C_after = self._micro_array[self._idx,self._dh_product_mask[i]] + + # Concentration change in the cell itself (observable part) + # depends on dilution factor. + del_C = C_after - C_before*self._meas_vol_dilution + + # Treat concentration change as the *mean* of all species in + # dh_product_mask. For a simple reaction A + B -> C, this would be + # the mean of the change in "C". For a more complicated reaction, + # this would be A + B -> C + D, this would be mean(dC,dD). + dC = np.mean(del_C) total_heat += dh_array[i]*self._dh_sign[i]*dC diff --git a/src/linkage/organizer/global_model.py b/src/linkage/organizer/global_model.py index 52d8912..336ca39 100644 --- a/src/linkage/organizer/global_model.py +++ b/src/linkage/organizer/global_model.py @@ -8,6 +8,8 @@ import copy class GlobalModel: + """ + """ def __init__(self, expt_list, @@ -27,12 +29,13 @@ def __init__(self, self._model_name = model_name self._expt_list = copy.deepcopy(expt_list) - # Indexes for slicing out binding model and enthalpy parameters + # Indexes for slicing out binding model self._bm_param_start_idx = None self._bm_param_end_idx = None + + # Indexes for slicing out and processing self._dh_param_start_idx = None self._dh_param_end_idx = None - self._dh_sign = None self._dh_product_mask = None @@ -46,6 +49,7 @@ def __init__(self, self._count_expt_points() self._get_enthalpy_param() self._process_expt_fudge() + self._calc_expt_normalization() self._build_point_map() def _load_model(self): @@ -117,7 +121,7 @@ def _get_enthalpy_param(self): need_enthalpies = False for expt in self._expt_list: for obs in expt.observables: - if expt.observables[obs]["obs_type"] == "itc": + if expt.observables[obs]["type"] == "itc": need_enthalpies = True break @@ -127,13 +131,27 @@ def _get_enthalpy_param(self): # Index of first enthalpy self._dh_param_start_idx = len(self._all_parameter_names) + # Enthalpy change over a titration step is determined by change in + # the concentration of microscopic species from the equilibrium. + # Ideally, there is a single species on one side of the reaction, + # so we can simply measure the change in the concentration of that + # species. This block of code figures out which side of the + # equilibrium has fewer species and declares that the "product" for + # accounting purposes. dh_sign records whether this is the right + # side of the reaction (forward) with +1 or the left side of the + # reaction (backward) with -1. By applying dh_sign, the final + # enthalpy is always correct relative to the reaction definition. self._dh_sign = [] self._dh_product_mask = [] + + # For each equilibrium for k in self._bm.equilibria: + # Get products and reactants of this equilibrium reactants = self._bm.equilibria[k][0] - products =self._bm.equilibria[k][1] + products = self._bm.equilibria[k][1] + # Figure out if products or reactants side has fewer species if len(products) <= len(reactants): self._dh_sign.append(1.0) key_species = products[:] @@ -141,6 +159,8 @@ def _get_enthalpy_param(self): self._dh_sign.append(-1.0) key_species = reactants[:] + # Create a mask that lets us grab the species we need to track + # from the _micro_array array. self._dh_product_mask.append(np.isin(self._bm.micro_species, key_species)) @@ -151,7 +171,7 @@ def _get_enthalpy_param(self): # Heats of dilution for k in self._bm.macro_species: - self._all_parameter_names.append(f"dil_{k}") + self._all_parameter_names.append(f"nuisance_dil_{k}") self._parameter_guesses.append(0.0) # Last enthalpy index is last entry @@ -166,7 +186,7 @@ def _process_expt_fudge(self): if expt.conc_to_float: - param_name = f"expt_{expt_counter}_{expt.conc_to_float}_fudge" + param_name = f"nuisance_expt_{expt_counter}_{expt.conc_to_float}_fudge" self._all_parameter_names.append(param_name) self._parameter_guesses.append(1.0) @@ -177,32 +197,150 @@ def _process_expt_fudge(self): else: self._fudge_list.append(None) + + def _calc_expt_normalization(self): + """ + Figure out how to normalize. Each unique 'obs' seen (e.g. heat, cd222, + etc.) is normalized to all values of that obs type seen across all + experiments. So, if there are three itc experiments, we will do a single + normalization across all three experiments. The normalization is + (value - mean(value))/stdev(value) where the mean and stdev are taken + over all experimental values with that obs. + """ + + # Create dictionary keying obs to a list of all observed values for that + # obs across experiments. + obs_values_seen = {} + for expt in self._expt_list: + for obs in expt.observables: + + keep = np.logical_not(expt.expt_data["ignore_point"]) + obs_values = list(expt.expt_data.loc[keep,obs]) + if obs not in obs_values_seen: + obs_values_seen[obs] = [] + + obs_values_seen[obs].extend(obs_values) + + # Create a normalization_params dictionary that keys obs to the mean and + # stdev of that obs. This allows other methods to normalize data on + # the fly. + self._normalization_params = {} + for obs in obs_values_seen: + + self._normalization_params[obs] = {} + + values = np.array(obs_values_seen[obs]) + values = values[np.logical_not(np.isnan(values))] + if len(values) == 0: + mean_value = 0 + stdev_value = 1 + else: + mean_value = np.mean(values) + stdev_value = np.std(values) + + self._normalization_params[obs]["mean"] = mean_value + self._normalization_params[obs]["stdev"] = stdev_value + + + def _add_point(self,point_idx,expt_idx,obs): + + # Information about observable and experimental data + expt = self._expt_list[expt_idx] + obs_info = expt.observables[obs] + expt_data = expt.expt_data.loc[expt.expt_data.index[point_idx],:] + if expt_data["ignore_point"]: + return + + if obs_info["type"] == "spec": + + den_index = np.where(self._bm.macro_species == obs_info["macrospecies"])[0][0] + + pt = SpecPoint(idx=point_idx, + expt_idx=expt_idx, + obs_key=obs, + micro_array=self._micro_arrays[-1], + macro_array=self._macro_arrays[-1], + del_macro_array=self._del_macro_arrays[-1], + obs_mask=np.isin(self._bm.micro_species, + obs_info["microspecies"]), + denom=den_index) + + elif obs_info["type"] == "itc": + + meas_vol_dilution = expt.expt_concs.loc[expt.expt_data.index[point_idx], + "meas_vol_dilution"] + + pt = ITCPoint(idx=point_idx, + expt_idx=expt_idx, + obs_key=obs, + micro_array=self._micro_arrays[-1], + macro_array=self._macro_arrays[-1], + del_macro_array=self._del_macro_arrays[-1], + meas_vol_dilution=meas_vol_dilution, + dh_param_start_idx=self._dh_param_start_idx, + dh_param_end_idx=self._dh_param_end_idx + 1, + dh_sign=self._dh_sign, + dh_product_mask=self._dh_product_mask) + + else: + obs_type = obs_info["type"] + err = f"The obs type '{obs_type}' is not recognized\n" + raise ValueError(err) + + # Record point, observations, and standard deviation + self._points.append(pt) + self._y_obs.append(expt_data[obs]) + self._y_stdev.append(self._points_per_expt[expt_idx]) + + # Get mean and stdev of obs for normalization + obs_mean = self._normalization_params[obs]["mean"] + obs_stdev = self._normalization_params[obs]["stdev"] + + # Record point normalization + self._y_norm_mean.append(obs_mean) + self._y_norm_stdev.append(obs_stdev) + self._y_obs_normalized.append((expt_data[obs] - obs_mean)/obs_stdev) + self._y_stdev_normalized.append(self._y_stdev[-1]/obs_stdev) + + def _build_point_map(self): # Lists of arrays that can be referenced by the individual points self._micro_arrays = [] self._macro_arrays = [] self._del_macro_arrays = [] + self._expt_syringe_concs = [] + # Points self._points = [] + + # Observed values self._y_obs = [] self._y_stdev = [] + + # Normalized observed values (and how to do it) + self._y_obs_normalized = [] + self._y_stdev_normalized = [] + + self._y_norm_mean = [] + self._y_norm_stdev = [] for expt_counter, expt in enumerate(self._expt_list): - # Each experiment will have a an array of microscopic species concentrations + # Each experiment has: + # + # 1. An array of microscopic species concentrations self._micro_arrays.append(np.ones((len(expt.expt_data), len(self._bm.micro_species)), dtype=float)*np.nan) - # ... and an array of macroscopic species concentrations + # 2. An array of macroscopic species concentrations macro_array = np.array(expt.expt_concs.loc[:,self._bm.macro_species], dtype=float) self._macro_arrays.append(macro_array) - # ... and an array of holding change in macro species relative to - # syringe. + # 3. An array of the change in macro species relative to syringe. syringe_concs = [] for s in self._bm.macro_species: if s in expt.syringe_contents: @@ -210,66 +348,58 @@ def _build_point_map(self): else: syringe_concs.append(0.0) - del_macro_array = np.array(syringe_concs,dtype=float) - macro_array - self._del_macro_arrays.append(del_macro_array) + syringe_concs = np.array(syringe_concs,dtype=float) + self._expt_syringe_concs.append(syringe_concs) + self._del_macro_arrays.append(syringe_concs - macro_array) + # For each observable for obs in expt.observables: - - obs_info = expt.observables[obs] - + + # Go through each experimental point for i in range(len(expt.expt_data)): + + # And try to add it + self._add_point(point_idx=i, + expt_idx=expt_counter, + obs=obs) - expt_data = expt.expt_data.loc[expt.expt_data.index[i],:] - - if expt_data["ignore_point"]: - continue - - if obs_info["obs_type"] == "spec": - - den_index = np.where(self._bm.macro_species == obs_info["denominator"])[0][0] - - pt = SpecPoint(idx=i, - expt_idx=expt_counter, - obs_key=obs, - micro_array=self._micro_arrays[-1], - macro_array=self._macro_arrays[-1], - del_macro_array=self._del_macro_arrays[-1], - obs_mask=np.isin(self._bm.micro_species, - obs_info["observable_species"]), - denom=den_index) - - elif obs_info["obs_type"] == "itc": + # Convert lists populated above into numpy arrays + self._y_obs = np.array(self._y_obs) + self._y_stdev = np.array(self._y_stdev) - meas_vol_dilution = expt.expt_concs.loc[expt.expt_data.index[i], - "meas_vol_dilution"] - - pt = ITCPoint(idx=i, - expt_idx=expt_counter, - obs_key=obs, - micro_array=self._micro_arrays[-1], - macro_array=self._macro_arrays[-1], - del_macro_array=self._del_macro_arrays[-1], - meas_vol_dilution=meas_vol_dilution, - dh_param_start_idx=self._dh_param_start_idx, - dh_param_end_idx=self._dh_param_end_idx + 1, - dh_sign=self._dh_sign, - dh_product_mask=self._dh_product_mask) - - else: - obs_type = obs_info["obs_type"] - err = f"The obs type '{obs_type}' is not recognized\n" - raise ValueError(err) + self._y_norm_mean = np.array(self._y_norm_mean) + self._y_norm_stdev = np.array(self._y_norm_stdev) - self._points.append(pt) - self._y_obs.append(expt_data[obs]) - self._y_stdev.append(self._points_per_expt[expt_counter]) + self._y_obs_normalized = np.array(self._y_obs_normalized) + self._y_stdev_normalized = np.array(self._y_stdev_normalized) + # Create calc arrays that are all nan at this point self._y_calc = np.ones(len(self._y_obs),dtype=float)*np.nan - self._y_obs = np.array(self._y_obs) - self._y_stdev = np.array(self._y_stdev)/np.sum(self._y_stdev) - + self._y_calc_normalized = np.ones(len(self._y_obs),dtype=float)*np.nan + def model_normalized(self,guesses): + """ + Model where each experiment is normalized to its mean and standard + deviation. Should be regressed against self.y_obs_normalized and + self.y_stdev_normalized, *not* self.y_obs and self.y_stdev. + + When this method is run, self.y_calc will be updated properly, + allowing self.y_calc and self.y_obs to be directly compared, even after + regressing against normalized values. + """ + + # Run model un-normalized (which updates self._y_calc) + y_calc = self.model(guesses) + + # Now normalize y_calc_norm + self._y_calc_norm = (y_calc - self._y_norm_mean)/self._y_norm_stdev + + # Return + return self._y_calc_norm + def model(self,guesses): + """ + """ # For each block of macro species for i in range(len(self._macro_arrays)): @@ -297,6 +427,11 @@ def model(self,guesses): self._micro_arrays[i][j,:] = self._bm.get_concs(param_array=this_param_array, macro_array=this_macro_array) + # Update del_macro_array + this_macro_array = self._macro_arrays[i].copy() + this_macro_array[fudge_species_index] *= fudge_value + self._del_macro_arrays[i] = self._expt_syringe_concs[i] - this_macro_array + # For each point, calculate the observable given the estimated microscopic # and macroscopic concentrations for i in range(len(self._points)): @@ -325,6 +460,31 @@ def y_stdev(self): """ return self._y_stdev + @property + def y_calc_normalized(self): + """ + Vector of calculated values where each experiment is normalized by + (obs - mean(obs))/stdev(obs). Pairs with y_obs_normalized. + """ + return self._y_calc_normalized + + @property + def y_obs_normalized(self): + """ + Vector of observed values where each experiment is normalized by + (obs - mean(obs))/stdev(obs). Pairs with y_calc_normalized and + y_stdev_normalized. + """ + return self._y_obs_normalized + + @property + def y_stdev_normalized(self): + """ + Vector of standard deviations of observed values normalized by + (obs - mean(obs))/stdev(obs). Pairs with y_obs_normalized. + """ + return self._y_stdev_normalized + @property def parameter_names(self): """ diff --git a/tests/conftest.py b/tests/conftest.py index 79cd60e..4f976b4 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -112,17 +112,26 @@ def fake_spec_and_itc_data(): cell_contents={"AT":50e-6, "CT":0.5e-3}, syringe_contents={"ET":1e-3}, - conc_to_float="AT") - - e.add_observable("cd222","spec",observable_species="I",denominator="AT") - e.add_observable("cd240","spec",observable_species=["I","A"],denominator="AT") + conc_to_float="AT", + cell_volume=1800) + + e.define_spectroscopic_observable(obs_column="cd222", + obs_stdev=0.1, + obs_microspecies="I", + obs_macrospecies="AT") + e.define_spectroscopic_observable(obs_column="cd240", + obs_stdev=0.1, + obs_microspecies=["I","A"], + obs_macrospecies="AT") # Load ITC data f = linkage.experiment.Experiment(itc_data, cell_contents={"CT":0.5e-3}, syringe_contents={"ET":1e-3}, - conc_to_float=None) - f.add_observable("heat","itc") + conc_to_float=None, + cell_volume=1800) + f.define_itc_observable(obs_column="heat", + obs_stdev=0.1) expt_list = [e,f] diff --git a/tests/linkage/experiment/test_experiment.py b/tests/linkage/experiment/test_experiment.py index 8cd766f..b70813a 100644 --- a/tests/linkage/experiment/test_experiment.py +++ b/tests/linkage/experiment/test_experiment.py @@ -147,11 +147,12 @@ def test_Experiment(): conc_to_float="NOT_THERE", cell_volume=cell_volume, constant_volume=True) - -def test_Experiment_add_observable(): + +def test_Experiment__define_generic_observable(): expt_data = pd.DataFrame({"injection":[0,1,1], - "obs":[1,2,3]}) + "obs":[1,2,3], + "obs_stdev":[0.1,0.2,0.3]}) cell_contents = {"A":10} syringe_contents = {"B":10} conc_to_float = None @@ -161,61 +162,78 @@ def test_Experiment_add_observable(): e = Experiment(expt_data=expt_data, cell_contents=cell_contents, syringe_contents=syringe_contents, - conc_to_float=conc_to_float, cell_volume=cell_volume, - constant_volume=constant_volume) - - e.add_observable(column_name="obs", - obs_type="spec", - observable_species=["anything"], - denominator="A") - assert e._observables["obs"]["obs_type"] == "spec" - assert np.array_equal(e._observables["obs"]["observable_species"],["anything"]) - assert e._observables["obs"]["denominator"] == "A" - - # Bad observable column - e = Experiment(expt_data=expt_data, - cell_contents=cell_contents, - syringe_contents=syringe_contents, conc_to_float=conc_to_float, - cell_volume=cell_volume, constant_volume=constant_volume) + + obs_column, obs_stdev_column = e._define_generic_observable(obs_column="obs", + obs_stdev="obs_stdev") + assert obs_column == "obs" + assert obs_stdev_column == "obs_stdev" with pytest.raises(ValueError): - e.add_observable(column_name="not_a_column", - obs_type="spec", - observable_species=["anything"], - denominator="A") + e._define_generic_observable(obs_column="not_a_column", + obs_stdev="obs_stdev") + + with pytest.raises(ValueError): + e._define_generic_observable(obs_column="injection", + obs_stdev="obs_stdev") - # Bad denominator + with pytest.raises(ValueError): + e._define_generic_observable(obs_column="obs", + obs_stdev="not_a_column") + + assert np.array_equal(e._expt_data["obs_stdev"],[0.1,0.2,0.3]) + obs_column, obs_stdev_column = e._define_generic_observable(obs_column="obs", + obs_stdev=1.5) + + assert obs_column == "obs" + assert obs_stdev_column == "obs_stdev" + assert np.array_equal(e._expt_data["obs_stdev"],[1.5,1.5,1.5]) + + # add twice, which should throw a warning e = Experiment(expt_data=expt_data, - cell_contents=cell_contents, - syringe_contents=syringe_contents, - conc_to_float=conc_to_float, - cell_volume=cell_volume, - constant_volume=constant_volume) + cell_contents=cell_contents, + syringe_contents=syringe_contents, + cell_volume=cell_volume, + conc_to_float=conc_to_float, + constant_volume=constant_volume) + + # add an itc observable + e.define_itc_observable(obs_column="obs",obs_stdev="obs_stdev") + + # should now warn because already added obs_column = "obs" to data + with pytest.warns(): + obs_column, obs_stdev_column = e._define_generic_observable(obs_column="obs", + obs_stdev="obs_stdev") + + +def test_Experiment_define_spectroscopic_observable(): + + expt_data = pd.DataFrame({"injection":[0,1,1], + "obs":[1,2,3], + "obs_stdev":[0.1,0.2,0.3]}) + cell_contents = {"A":10} + syringe_contents = {"B":10} + conc_to_float = None + cell_volume = 100 + constant_volume = False - with pytest.raises(ValueError): - e.add_observable(column_name="obs", - obs_type="spec", - observable_species=["anything"], - denominator="not_a_species") - - # No observable species e = Experiment(expt_data=expt_data, cell_contents=cell_contents, syringe_contents=syringe_contents, - conc_to_float=conc_to_float, cell_volume=cell_volume, + conc_to_float=conc_to_float, constant_volume=constant_volume) - - with pytest.raises(ValueError): - e.add_observable(column_name="obs", - obs_type="spec", - observable_species=None, - denominator="A") - # Bad observable species + e.define_spectroscopic_observable(obs_column="obs", + obs_stdev="obs_stdev", + obs_microspecies=["anything"], + obs_macrospecies="A") + assert e._observables["obs"]["type"] == "spec" + assert np.array_equal(e._observables["obs"]["microspecies"],["anything"]) + assert e._observables["obs"]["macrospecies"] == "A" + e = Experiment(expt_data=expt_data, cell_contents=cell_contents, syringe_contents=syringe_contents, @@ -223,75 +241,104 @@ def test_Experiment_add_observable(): cell_volume=cell_volume, constant_volume=constant_volume) + # Bad observable column with pytest.raises(ValueError): - e.add_observable(column_name="obs", - obs_type="spec", - observable_species=1, - denominator="A") - + e.define_spectroscopic_observable(obs_column="not_a_column", + obs_stdev="obs_stdev", + obs_microspecies=["anything"], + obs_macrospecies="A") + + # Bad obs_stdev column + with pytest.raises(ValueError): + e.define_spectroscopic_observable(obs_column="obs", + obs_stdev="not_a_column", + obs_microspecies=["anything"], + obs_macrospecies="A") + + # good obs_stdev, but as float + e.define_spectroscopic_observable(obs_column="obs", + obs_stdev=1.5, + obs_microspecies=["anything"], + obs_macrospecies="A") + assert np.array_equal(e._expt_data["obs_stdev"],[1.5,1.5,1.5]) + - # Observable species as list e = Experiment(expt_data=expt_data, cell_contents=cell_contents, syringe_contents=syringe_contents, conc_to_float=conc_to_float, cell_volume=cell_volume, constant_volume=constant_volume) - - e.add_observable(column_name="obs", - obs_type="spec", - observable_species="anything", - denominator="A") - assert e._observables["obs"]["obs_type"] == "spec" - assert np.array_equal(e._observables["obs"]["observable_species"],["anything"]) - assert e._observables["obs"]["denominator"] == "A" - - # Disallowed column name + # Bad obs_macrospecies column + with pytest.raises(ValueError): + e.define_spectroscopic_observable(obs_column="obs", + obs_stdev="obs_stdev", + obs_microspecies=["anything"], + obs_macrospecies="not_in_cell_or_syringe") + + # obs_microspecies as a single value + e.define_spectroscopic_observable(obs_column="obs", + obs_stdev=1.5, + obs_microspecies="anything", + obs_macrospecies="A") + assert np.array_equal(e._observables["obs"]["microspecies"],["anything"]) + + # obs_microspecies as multiple values e = Experiment(expt_data=expt_data, cell_contents=cell_contents, syringe_contents=syringe_contents, conc_to_float=conc_to_float, cell_volume=cell_volume, constant_volume=constant_volume) + e.define_spectroscopic_observable(obs_column="obs", + obs_stdev=1.5, + obs_microspecies=["anything","else"], + obs_macrospecies="A") + assert np.array_equal(e._observables["obs"]["microspecies"],["anything","else"]) - with pytest.raises(ValueError): - e.add_observable(column_name="injection", - obs_type="spec", - observable_species=["anything"], - denominator="A") - - # Send in ITC experiment + # bad obs_microspecies e = Experiment(expt_data=expt_data, cell_contents=cell_contents, syringe_contents=syringe_contents, conc_to_float=conc_to_float, cell_volume=cell_volume, constant_volume=constant_volume) - - e.add_observable(column_name="obs", - obs_type="itc", - observable_species=None, - denominator=None) - assert e._observables["obs"]["obs_type"] == "itc" - assert e._observables["obs"]["observable_species"] is None - assert e._observables["obs"]["denominator"] is None - - # Observable not recognized + with pytest.raises(ValueError): + e.define_spectroscopic_observable(obs_column="obs", + obs_stdev="obs_stdev", + obs_microspecies=1.5, + obs_macrospecies="A") + + +def test_Experiment_define_itc_observable(): + + expt_data = pd.DataFrame({"injection":[0,1,1], + "obs":[1,2,3], + "obs_stdev":[0.1,0.2,0.3]}) + cell_contents = {"A":10} + syringe_contents = {"B":10} + conc_to_float = None + cell_volume = 100 + constant_volume = False + + # This function is a light wrapper for _define_generic_observable. Don't + # check it's validation, but do make sure we assign values correctly. e = Experiment(expt_data=expt_data, cell_contents=cell_contents, syringe_contents=syringe_contents, conc_to_float=conc_to_float, cell_volume=cell_volume, constant_volume=constant_volume) - - with pytest.raises(ValueError): - e.add_observable(column_name="obs", - obs_type="not_really_osbervable", - observable_species=["anything"], - denominator="A") - + + e.define_itc_observable(obs_column="obs", + obs_stdev="obs_stdev") + + assert len(e._observables["obs"]) == 2 + assert e._observables["obs"]["type"] == "itc" + assert e._observables["obs"]["stdev_column"] == "obs_stdev" + def test_add_expt_column(): diff --git a/tests/linkage/organizer/test_global_model.py b/tests/linkage/organizer/test_global_model.py index cd180db..a6a8655 100644 --- a/tests/linkage/organizer/test_global_model.py +++ b/tests/linkage/organizer/test_global_model.py @@ -7,6 +7,8 @@ from linkage.experiment.point.spec_point import SpecPoint from linkage.experiment.point.itc_point import ITCPoint +from linkage.experiment.experiment import Experiment + import numpy as np import pandas as pd import copy @@ -36,7 +38,6 @@ def test_GlobalModel__load_model(fake_spec_and_itc_data): assert gf._model_name == "SixStateEDTA" assert issubclass(type(gf._bm),linkage.models.six_state_edta.SixStateEDTA) - this_expt_list = copy.deepcopy(base_expt_list) with pytest.raises(ValueError): gf = GlobalModel(model_name="not_a_model", @@ -109,7 +110,8 @@ def test_GlobalModel__get_enthalpy_param(fake_spec_and_itc_data): assert gf._dh_param_start_idx is not None assert gf._dh_param_end_idx is not None - expected = ['dH_I','dH_E','dH_1','dH_2','dH_3','dH_4',"dil_AT","dil_CT","dil_ET"] + expected = ['dH_I','dH_E','dH_1','dH_2','dH_3','dH_4', + "nuisance_dil_AT","nuisance_dil_CT","nuisance_dil_ET"] dh_param = gf._all_parameter_names[gf._dh_param_start_idx:gf._dh_param_end_idx + 1] assert np.array_equal(expected,dh_param) @@ -124,6 +126,7 @@ def test_GlobalModel__get_enthalpy_param(fake_spec_and_itc_data): assert np.sum(gf._dh_product_mask[i]) == 1 assert np.arange(9,dtype=int)[gf._dh_product_mask[i]] == order_in_class[i] + assert np.array_equal(gf._dh_sign,[1,1,1,1,1,1]) # Remove itc experiment; should have no enthalpies this_expt_list = copy.deepcopy(base_expt_list) @@ -142,12 +145,72 @@ def test_GlobalModel__process_expt_fudge(fake_spec_and_itc_data): this_expt_list = copy.deepcopy(base_expt_list) gf = GlobalModel(model_name="SixStateEDTA", expt_list=this_expt_list) - assert gf.parameter_names[-1] == "expt_0_AT_fudge" + assert gf.parameter_names[-1] == "nuisance_expt_0_AT_fudge" assert gf.parameter_guesses[-1] == 1.0 assert gf._fudge_list[0][0] == 0 assert gf._fudge_list[0][1] == len(gf.parameter_names) - 1 assert gf._fudge_list[1] is None +def test_GlobalModel__calc_expt_normalization(fake_spec_and_itc_data): + + base_expt_list = copy.deepcopy(fake_spec_and_itc_data) + + # Basic check of output + this_expt_list = copy.deepcopy(base_expt_list) + gf = GlobalModel(model_name="SixStateEDTA", + expt_list=this_expt_list) + + assert len(gf._normalization_params) == 3 + assert np.array_equal(list(gf._normalization_params["cd222"]),["mean","stdev"]) + assert np.array_equal(list(gf._normalization_params["cd240"]),["mean","stdev"]) + assert np.array_equal(list(gf._normalization_params["heat"]),["mean","stdev"]) + + # Make sure calculated values are correct when we dump in specific values + this_expt_list = copy.deepcopy(base_expt_list) + this_expt_list[0].expt_data["cd222"] = 1 + this_expt_list[0].expt_data.loc[this_expt_list[0].expt_data.index[0],"cd222"] = 0 + this_expt_list[0].expt_data["cd240"] = np.random.choice([1,2],50) + this_expt_list[1].expt_data["heat"] = np.nan + + gf = GlobalModel(model_name="SixStateEDTA", + expt_list=this_expt_list) + + # Should be 1 and 0. All values were 1. + assert np.isclose(gf._normalization_params["cd222"]["mean"],0.98) + assert np.isclose(gf._normalization_params["cd222"]["stdev"],0.13999999999) + + # There is a small chance this fails numerically if the random choice above + # was super extreme. + assert gf._normalization_params["cd240"]["mean"] > 1 + assert gf._normalization_params["cd240"]["mean"] < 2 + assert gf._normalization_params["cd240"]["stdev"] > 0.2 + assert gf._normalization_params["cd240"]["stdev"] < 0.8 + + # These will be 0 and 1 if all values were nan + assert gf._normalization_params["heat"]["mean"] == 0 + assert gf._normalization_params["heat"]["stdev"] == 1 + + # Make sure it is normalizing correctly between experiments with shared + # observables. + this_expt_list = copy.deepcopy(base_expt_list) + this_expt_list.append(copy.deepcopy(this_expt_list[0])) + this_expt_list[0].expt_data["cd222"] = 1 + this_expt_list[2].expt_data["cd222"] = 2 + + gf = GlobalModel(model_name="SixStateEDTA", + expt_list=this_expt_list) + + # Should be 1 and 0. All values were 1. + assert np.isclose(gf._normalization_params["cd222"]["mean"],1.5) + assert np.isclose(gf._normalization_params["cd222"]["stdev"],0.5) + +def test_GlobalModel__add_point(): + + # This is a difficult method to test on its own because of how it integrates + # with other attributes in the class. It's mostly tested by build_point_map... + pass + + def test_GlobalModel__build_point_map(fake_spec_and_itc_data): base_expt_list = copy.deepcopy(fake_spec_and_itc_data) @@ -156,34 +219,55 @@ def test_GlobalModel__build_point_map(fake_spec_and_itc_data): gf = GlobalModel(model_name="SixStateEDTA", expt_list=this_expt_list) + # Test micro_array assert len(gf._micro_arrays) == 2 assert gf._micro_arrays[0].shape[1] == len(gf._bm.micro_species) assert gf._micro_arrays[1].shape[1] == len(gf._bm.micro_species) + # Test macro_array assert len(gf._macro_arrays) == 2 assert gf._macro_arrays[0].shape[1] == len(gf._bm.macro_species) assert gf._macro_arrays[1].shape[1] == len(gf._bm.macro_species) + # Test del_macro_array + assert len(gf._del_macro_arrays) == 2 + assert gf._del_macro_arrays[0].shape[1] == len(gf._bm.macro_species) + assert gf._del_macro_arrays[1].shape[1] == len(gf._bm.macro_species) + + # Test expt_syring_concs + assert len(gf._expt_syringe_concs) == 2 + assert len(gf._expt_syringe_concs[0]) == 3 + assert len(gf._expt_syringe_concs[1]) == 3 + + # Test points num_points = 0 for expt in this_expt_list: num_obs = len(expt.observables) num_not_ignore = np.sum(np.logical_not(expt._expt_data["ignore_point"])) num_points += num_obs*num_not_ignore - num_spec = sum([issubclass(type(p),SpecPoint) for p in gf._points]) num_itc = sum([issubclass(type(p),ITCPoint) for p in gf._points]) assert np.array_equal(gf._points_per_expt,[num_spec,num_itc]) assert num_points == len(gf._points) + + # Test y_obs, y_stdev, y_calc assert num_points == len(gf._y_obs) assert num_points == len(gf._y_stdev) assert num_points == len(gf._y_calc) - + # Test y_obs_normalized, y_stdev_normalized + assert num_points == len(gf._y_obs_normalized) + assert num_points == len(gf._y_stdev_normalized) + + # Test y_norm_mean and y_norm_stdev + assert num_points == len(gf._y_norm_mean) + assert num_points == len(gf._y_norm_stdev) + this_expt_list = copy.deepcopy(base_expt_list) - this_expt_list[0].observables["cd222"]["obs_type"] = "not_really" + this_expt_list[0].observables["cd222"]["type"] = "not_really" with pytest.raises(ValueError): gf = GlobalModel(model_name="SixStateEDTA", expt_list=this_expt_list) \ No newline at end of file From 4ae3b01af76e06ec1ad5f4584cec74cb28415bbb Mon Sep 17 00:00:00 2001 From: Michael Harms Date: Tue, 30 Jul 2024 15:52:05 -0700 Subject: [PATCH 13/17] simplified logic in titrator --- src/linkage/experiment/titrator.py | 41 ++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/linkage/experiment/titrator.py b/src/linkage/experiment/titrator.py index 3ddf479..ada0b59 100644 --- a/src/linkage/experiment/titrator.py +++ b/src/linkage/experiment/titrator.py @@ -5,7 +5,27 @@ def sync_cell_and_syringe(cell_contents, syringe_contents): + """ + Make sure the same species are in both cell_contents and syringe_contents. + Any species present in one but not the other are assigned concentrations + of 0.0. + + Parameters + ---------- + cell_contents : dict + dictionary with species as keys and cell concentrations as values + syringe_contents : dict + dictionary with species as keys and syringe concentrations as values + Returns + ------- + species : list + sorted list of all species seen + cell_contents : dict + cell_contents dict with concs of zero for missing species + syringe_contents : dict + syringe_contents dict with concs of zero for missing species + """ if not issubclass(type(cell_contents),dict): err = "cell_contents should be a dictionary with initial cell concs\n" raise ValueError(err) @@ -67,34 +87,32 @@ def _titr_increase_volume(cell_contents, out): # For each injection - start_vol = cell_volume + current_volume = cell_volume meas_vol_dilution = 1 for i in range(len(injection_array)): - # Get starting volume - if len(out["injection"]) > 0: - start_vol = out["volume"][-1] - meas_vol_dilution = (1 - injection_array[i]/cell_volume) + meas_vol_dilution = (1 - injection_array[i]/cell_volume) # Get volume after this injection is injected - new_vol = start_vol + injection_array[i] + new_volume = current_volume + injection_array[i] # Record current volume and injection out["injection"].append(injection_array[i]) - out["volume"].append(new_vol) + out["volume"].append(new_volume) out["meas_vol_dilution"].append(meas_vol_dilution) # Update cell concs based on injected titrant for s in cell_contents.keys(): - prev_conc = cell_contents[s] - - a = start_vol*prev_conc + a = current_volume*cell_contents[s] b = injection_array[i]*syringe_contents[s] - cell_contents[s] = (a + b)/new_vol + cell_contents[s] = (a + b)/new_volume out[s].append(cell_contents[s]) + # Update volume + current_volume = new_volume + return out @@ -136,6 +154,7 @@ def titrator(cell_contents, versus injections in the experiment """ + # Make sure all species are present in the cell and syringe dictionaries species, cell_contents, syringe_contents = sync_cell_and_syringe(cell_contents, syringe_contents) From b0097b3a6ebebfc95c367ba90b644a0d3f3a7fbf Mon Sep 17 00:00:00 2001 From: Michael Harms Date: Tue, 30 Jul 2024 16:03:26 -0700 Subject: [PATCH 14/17] add better simulated data to test suite --- tests/conftest.py | 5 +- tests/data/simulated_itc/binding_expt.csv | 27 +++++++ tests/data/simulated_itc/blank_expt.csv | 27 +++++++ tests/data/simulated_itc/generate_itc_data.py | 70 +++++++++++++++++++ 4 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 tests/data/simulated_itc/binding_expt.csv create mode 100644 tests/data/simulated_itc/blank_expt.csv create mode 100644 tests/data/simulated_itc/generate_itc_data.py diff --git a/tests/conftest.py b/tests/conftest.py index 4f976b4..fc45304 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -91,8 +91,9 @@ def get_files(base_dir): return output @pytest.fixture(scope="module") -def example_xyz(): - return get_files(os.path.join("data","example-xyz")) +def simulated_itc(): + + return get_files(os.path.join("data","simulated_itc")) @pytest.fixture(scope="module") def fake_spec_and_itc_data(): diff --git a/tests/data/simulated_itc/binding_expt.csv b/tests/data/simulated_itc/binding_expt.csv new file mode 100644 index 0000000..a2a84f9 --- /dev/null +++ b/tests/data/simulated_itc/binding_expt.csv @@ -0,0 +1,27 @@ +injection,heat +0.0, +2.0,-0.6698887856953665 +2.0,-0.6653981051510617 +2.0,-0.6628770104848354 +2.0,-0.6572600039805307 +2.0,-0.6544483711885344 +2.0,-0.6504849636862378 +2.0,-0.6404583989405751 +2.0,-0.6376838389904914 +2.0,-0.6378359001575715 +2.0,-0.633540956451369 +2.0,-0.6251375384830915 +2.0,-0.6201433401680164 +2.0,-0.6151452055627816 +2.0,-0.5484958725734232 +2.0,-0.2920939813000814 +2.0,-0.23494590560590042 +2.0,-0.22694817238908618 +2.0,-0.22704683549278215 +2.0,-0.2229765373934299 +2.0,-0.22315231943129848 +2.0,-0.2261348200467626 +2.0,-0.22047538531018618 +2.0,-0.21948399323774065 +2.0,-0.21865938338939592 +2.0,-0.2160287541946412 diff --git a/tests/data/simulated_itc/blank_expt.csv b/tests/data/simulated_itc/blank_expt.csv new file mode 100644 index 0000000..0c60f8a --- /dev/null +++ b/tests/data/simulated_itc/blank_expt.csv @@ -0,0 +1,27 @@ +injection,heat +0.0, +2.0,-0.2442462588685921 +2.0,-0.24295005228246766 +2.0,-0.23557114377762883 +2.0,-0.23844502898873843 +2.0,-0.23933754638183913 +2.0,-0.2443435490673292 +2.0,-0.23589295931746368 +2.0,-0.2380656119509871 +2.0,-0.2330682723652203 +2.0,-0.2279854541512425 +2.0,-0.23190528384682552 +2.0,-0.23464743869038096 +2.0,-0.2366097006847176 +2.0,-0.22320395204965413 +2.0,-0.22823351798594146 +2.0,-0.2300511120307936 +2.0,-0.2209894117300196 +2.0,-0.21866333693069204 +2.0,-0.223161934647072 +2.0,-0.21805199016761126 +2.0,-0.21495030878756455 +2.0,-0.2142776639631268 +2.0,-0.20871828135605286 +2.0,-0.2174045643244037 +2.0,-0.21417738451534674 diff --git a/tests/data/simulated_itc/generate_itc_data.py b/tests/data/simulated_itc/generate_itc_data.py new file mode 100644 index 0000000..205a795 --- /dev/null +++ b/tests/data/simulated_itc/generate_itc_data.py @@ -0,0 +1,70 @@ + +import linkage + +import numpy as np +import pandas as pd + +def create_fake_itc_data(): + + np.random.seed(20070401) + + # Load ITC data + itc_data = pd.DataFrame({"injection":2*np.ones(25), + "heat":np.random.normal(0,1,25)}) + + a = linkage.experiment.Experiment(expt_data=itc_data.copy(), + cell_contents={}, + syringe_contents={"ET":5e-3}, + conc_to_float=None, + cell_volume=280) + a.define_itc_observable(obs_column="heat", + obs_stdev=0.1) + + + b = linkage.experiment.Experiment(expt_data=itc_data.copy(), + cell_contents={"CT":0.5e-3}, + syringe_contents={"ET":5e-3}, + conc_to_float=None, + cell_volume=280) + b.define_itc_observable(obs_column="heat", + obs_stdev=0.1) + + expt_list = [a,b] + + gm = linkage.GlobalModel(model_name="CaEDTA", + expt_list=expt_list) + + # log10(KE), dH_C, dH_E, dH_EC + guesses = np.array([7,-11900,0,-50]) + + err = 0.003 + initial_values = gm.model(guesses) + gm._y_obs = gm._y_calc + np.random.normal(0,err,len(gm._y_calc)) + gm._y_stdev = np.ones(len(gm._y_obs))*err + + df = gm.as_df + + # for expt in np.unique(df["expt_id"]): + # this_df = df.loc[df["expt_id"] == expt,:] + # plt.plot(this_df["ET"],this_df["y_obs"],'o') + + + names = ["blank","binding"] + for expt in np.unique(gm.as_df["expt_id"]): + this_df = gm.as_df.loc[gm.as_df["expt_id"] == expt,:] + + inj = [] + inj.extend(list(gm._expt_list[expt].expt_data.loc[:,"injection"])) + + heat = [np.nan] + heat.extend(list(this_df.loc[:,"y_obs"])) + + out = {} + out["injection"] = np.array(inj) + out["heat"] = np.array(heat) + + out_df = pd.DataFrame(out) + + out_df.to_csv(f'{names[expt]}_expt.csv',index=None) + +create_fake_itc_data() \ No newline at end of file From e8899358a0549bc27894284a4d85a3bc5bc73dfc Mon Sep 17 00:00:00 2001 From: Michael Harms Date: Tue, 30 Jul 2024 16:27:31 -0700 Subject: [PATCH 15/17] added real data to tests --- MANIFEST.in | 4 +- pyproject.toml | 2 +- tests/conftest.py | 25 +++++++++- tests/data/simulated_itc/generate_itc_data.py | 47 ++++++++++++------ tests/data/simulated_itc/simulated_itc.pdf | Bin 0 -> 13939 bytes tests/linkage/organizer/test_global_model.py | 15 +++--- 6 files changed, 67 insertions(+), 26 deletions(-) create mode 100644 tests/data/simulated_itc/simulated_itc.pdf diff --git a/MANIFEST.in b/MANIFEST.in index 4b15d8e..81cf9b9 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,2 @@ -include src/linkage/data/ -include src/linkage/data/* +include tests/data/ +include tests/data/* diff --git a/pyproject.toml b/pyproject.toml index 143ca2d..c03703f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ version = {attr = "linkage.__version__.__version__"} [tool.setuptools.package-data] "*" = [ - "src/linkage/data/*" + "tests/data/*" ] [project] diff --git a/tests/conftest.py b/tests/conftest.py index fc45304..990c862 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -84,6 +84,9 @@ def get_files(base_dir): # make sure output is sorted stably for k in output: + if issubclass(type(output[k]),str): + continue + new_output = list(output[k]) new_output.sort() output[k] = new_output @@ -93,7 +96,27 @@ def get_files(base_dir): @pytest.fixture(scope="module") def simulated_itc(): - return get_files(os.path.join("data","simulated_itc")) + files = get_files(os.path.join("data","simulated_itc")) + + blank = linkage.Experiment(expt_data=files["blank_expt.csv"], + cell_contents={}, + syringe_contents={"ET":5e-3}, + cell_volume=280) + blank.define_itc_observable(obs_column="heat", + obs_stdev=0.003) + + expt = linkage.Experiment(expt_data=files["binding_expt.csv"], + cell_contents={"CT":0.5e-3}, + syringe_contents={"ET":5e-3}, + cell_volume=280) + expt.define_itc_observable(obs_column="heat", + obs_stdev=0.003) + + guesses = np.array([7,-11900,0,-50]) + + return {"files":files, + "expt_list":[blank,expt], + "guesses":guesses} @pytest.fixture(scope="module") def fake_spec_and_itc_data(): diff --git a/tests/data/simulated_itc/generate_itc_data.py b/tests/data/simulated_itc/generate_itc_data.py index 205a795..0778266 100644 --- a/tests/data/simulated_itc/generate_itc_data.py +++ b/tests/data/simulated_itc/generate_itc_data.py @@ -3,15 +3,25 @@ import numpy as np import pandas as pd +from matplotlib import pyplot as plt def create_fake_itc_data(): np.random.seed(20070401) - # Load ITC data + # Randomness we are going to inject into our simulated results + err = 0.003 + + # Names of series + names = ["blank","binding"] + + # Create fake data that has the number of injections we want, but no sane + # values. itc_data = pd.DataFrame({"injection":2*np.ones(25), "heat":np.random.normal(0,1,25)}) + # Create an experiment from the fake data where we titrate ET into an + # empty cell a = linkage.experiment.Experiment(expt_data=itc_data.copy(), cell_contents={}, syringe_contents={"ET":5e-3}, @@ -21,6 +31,8 @@ def create_fake_itc_data(): obs_stdev=0.1) + # Create an experiment from the fake data where we titrate ET into a cell + # with CT. b = linkage.experiment.Experiment(expt_data=itc_data.copy(), cell_contents={"CT":0.5e-3}, syringe_contents={"ET":5e-3}, @@ -29,27 +41,34 @@ def create_fake_itc_data(): b.define_itc_observable(obs_column="heat", obs_stdev=0.1) - expt_list = [a,b] - + # Create a linkage model using the CaEDTA binding model and these two + # experiments. gm = linkage.GlobalModel(model_name="CaEDTA", - expt_list=expt_list) + expt_list=[a,b]) - # log10(KE), dH_C, dH_E, dH_EC + # [log10('KE'), 'dH_E', 'nuisance_dil_CT', 'nuisance_dil_ET'] guesses = np.array([7,-11900,0,-50]) - err = 0.003 - initial_values = gm.model(guesses) - gm._y_obs = gm._y_calc + np.random.normal(0,err,len(gm._y_calc)) + # Calculate the values for our model. This creates _y_calc + y_calc = gm.model(guesses) + + # Hack for the simulation. Set y_obs and y_stdev to y_calc + gm._y_obs = y_calc + np.random.normal(0,err,len(y_calc)) gm._y_stdev = np.ones(len(gm._y_obs))*err + # Plot results + fig, ax = plt.subplots(1,figsize=(6,6)) df = gm.as_df + for expt in np.unique(df["expt_id"]): + this_df = df.loc[df["expt_id"] == expt,:] + ax.plot(this_df["ET"],this_df["y_obs"],'o',label=names[expt]) + + ax.legend() + ax.set_xlabel("injection number") + ax.set_ylabel("measured heat") + fig.savefig("simulated_itc.pdf") - # for expt in np.unique(df["expt_id"]): - # this_df = df.loc[df["expt_id"] == expt,:] - # plt.plot(this_df["ET"],this_df["y_obs"],'o') - - - names = ["blank","binding"] + # Now create output files for expt in np.unique(gm.as_df["expt_id"]): this_df = gm.as_df.loc[gm.as_df["expt_id"] == expt,:] diff --git a/tests/data/simulated_itc/simulated_itc.pdf b/tests/data/simulated_itc/simulated_itc.pdf new file mode 100644 index 0000000000000000000000000000000000000000..af7706fb203130088d18557f6ead4dc53e455b37 GIT binary patch literal 13939 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 literal 0 HcmV?d00001 diff --git a/tests/linkage/organizer/test_global_model.py b/tests/linkage/organizer/test_global_model.py index a6a8655..24f7d05 100644 --- a/tests/linkage/organizer/test_global_model.py +++ b/tests/linkage/organizer/test_global_model.py @@ -13,18 +13,17 @@ import pandas as pd import copy -def test_GlobalModel_integrated(fake_spec_and_itc_data): +def test_GlobalModel_integrated(simulated_itc): - base_expt_list = copy.deepcopy(fake_spec_and_itc_data) - this_expt_list = copy.deepcopy(base_expt_list) + expt_list = simulated_itc["expt_list"] + guesses = simulated_itc["guesses"] - gf = GlobalModel(model_name="SixStateEDTA", + this_expt_list = copy.deepcopy(expt_list) + + gf = GlobalModel(model_name="CaEDTA", expt_list=this_expt_list) - gf.model(gf.parameter_guesses) - - df = gf.as_df - assert issubclass(type(df),pd.DataFrame) + gf.model(guesses) def test_GlobalModel__load_model(fake_spec_and_itc_data): From ded7b3dfc4a432d9a35a53ed72e81b882b10627b Mon Sep 17 00:00:00 2001 From: Michael Harms Date: Tue, 30 Jul 2024 17:43:19 -0700 Subject: [PATCH 16/17] regression with standard deviations now works --- src/linkage/experiment/experiment.py | 4 ++- src/linkage/models/ca_edta.py | 4 --- src/linkage/models/six_state_edta.py | 2 -- src/linkage/organizer/global_model.py | 4 +-- tests/data/simulated_itc/simulated_itc.pdf | Bin 13939 -> 13939 bytes tests/linkage/experiment/test_experiment.py | 26 ++++++++++++++++++-- 6 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/linkage/experiment/experiment.py b/src/linkage/experiment/experiment.py index dd71b55..3b3f3e5 100644 --- a/src/linkage/experiment/experiment.py +++ b/src/linkage/experiment/experiment.py @@ -48,7 +48,6 @@ def _preprocess_df(expt_data): if "ignore_point" not in expt_data.columns: expt_data["ignore_point"] = np.zeros(len(expt_data),dtype=bool) - # If there is no "0" injections start -- like in ITC, for example -- add this with # np.nan for all non-injection values if not np.isclose(expt_data.loc[expt_data.index[0],"injection"],0): @@ -160,6 +159,9 @@ def _define_generic_observable(self, w = f"obs_column '{obs_column}' was already adding. Overwriting\n" warnings.warn(w) + # Make sure any missing data is ignored. + set_to_ignore = np.isnan(self._expt_data[obs_column]) + self._expt_data.loc[set_to_ignore,"ignore_point"] = True return obs_column, obs_stdev_column diff --git a/src/linkage/models/ca_edta.py b/src/linkage/models/ca_edta.py index d33dd6f..9b9f8fd 100644 --- a/src/linkage/models/ca_edta.py +++ b/src/linkage/models/ca_edta.py @@ -49,7 +49,3 @@ def macro_species(self): @property def micro_species(self): return np.array(["C", "E", "EC"]) - - @property - def reactants(self): - pass \ No newline at end of file diff --git a/src/linkage/models/six_state_edta.py b/src/linkage/models/six_state_edta.py index 5b21411..2e27d4c 100644 --- a/src/linkage/models/six_state_edta.py +++ b/src/linkage/models/six_state_edta.py @@ -105,8 +105,6 @@ def get_concs(self,param_array,macro_array): return np.array([I, A, C, E, AC1, AC2, AC3, AC4, EC]) - - @property def param_names(self): return np.array(["KI","KE","K1","K2","K3","K4"]) diff --git a/src/linkage/organizer/global_model.py b/src/linkage/organizer/global_model.py index 336ca39..80425bb 100644 --- a/src/linkage/organizer/global_model.py +++ b/src/linkage/organizer/global_model.py @@ -13,7 +13,7 @@ class GlobalModel: def __init__(self, expt_list, - model_name="SixStateEDTA"): + model_name): """ Initialize a global fit. @@ -291,7 +291,7 @@ def _add_point(self,point_idx,expt_idx,obs): # Record point, observations, and standard deviation self._points.append(pt) self._y_obs.append(expt_data[obs]) - self._y_stdev.append(self._points_per_expt[expt_idx]) + self._y_stdev.append(expt_data[obs_info["stdev_column"]]) # Get mean and stdev of obs for normalization obs_mean = self._normalization_params[obs]["mean"] diff --git a/tests/data/simulated_itc/simulated_itc.pdf b/tests/data/simulated_itc/simulated_itc.pdf index af7706fb203130088d18557f6ead4dc53e455b37..35562cef951755177d0296a8c48f78feca858e7c 100644 GIT binary patch delta 17 YcmeyI^EqdOg%OLXsfp!g8zXZT07SJ05C8xG delta 17 YcmeyI^EqdOg%OLPp{c=U8zXZT07OCt00000 diff --git a/tests/linkage/experiment/test_experiment.py b/tests/linkage/experiment/test_experiment.py index b70813a..61d136b 100644 --- a/tests/linkage/experiment/test_experiment.py +++ b/tests/linkage/experiment/test_experiment.py @@ -199,14 +199,36 @@ def test_Experiment__define_generic_observable(): conc_to_float=conc_to_float, constant_volume=constant_volume) - # add an itc observable + # add an itc observable (have to add completely because _define_generic + # does not actually update _observable dict) e.define_itc_observable(obs_column="obs",obs_stdev="obs_stdev") # should now warn because already added obs_column = "obs" to data with pytest.warns(): obs_column, obs_stdev_column = e._define_generic_observable(obs_column="obs", obs_stdev="obs_stdev") - + + # Send in a nan and make sure it is set to be ignored + expt_data = pd.DataFrame({"injection":[0,1,1], + "obs":[1,np.nan,3], + "obs_stdev":[0.1,0.2,0.3]}) + cell_contents = {"A":10} + syringe_contents = {"B":10} + conc_to_float = None + cell_volume = 100 + constant_volume = False + + e = Experiment(expt_data=expt_data, + cell_contents=cell_contents, + syringe_contents=syringe_contents, + cell_volume=cell_volume, + conc_to_float=conc_to_float, + constant_volume=constant_volume) + e._define_generic_observable(obs_column="obs", + obs_stdev="obs_stdev") + assert np.array_equal(e._expt_data["ignore_point"], + [False,True,False]) + def test_Experiment_define_spectroscopic_observable(): From e75bfe31aada2c97d2978987290d291ae9196227 Mon Sep 17 00:00:00 2001 From: Michael Harms Date: Wed, 31 Jul 2024 12:34:18 -0700 Subject: [PATCH 17/17] added notebooks, better coverage test --- docs/badges/coverage-badge.svg | 2 +- docs/badges/tests-badge.svg | 2 +- notebooks/data/itc_binding_expt.csv | 27 + notebooks/data/itc_blank_expt.csv | 27 + notebooks/global-fit.ipynb | 381 +++++++++ reports/flake.txt | 1137 +++++++++++++++++---------- reports/junit/junit.xml | 2 +- run_all_tests.sh | 9 +- src/linkage/__version__.py | 2 +- 9 files changed, 1165 insertions(+), 424 deletions(-) create mode 100644 notebooks/data/itc_binding_expt.csv create mode 100644 notebooks/data/itc_blank_expt.csv create mode 100644 notebooks/global-fit.ipynb diff --git a/docs/badges/coverage-badge.svg b/docs/badges/coverage-badge.svg index d6e7b66..239ca49 100644 --- a/docs/badges/coverage-badge.svg +++ b/docs/badges/coverage-badge.svg @@ -1 +1 @@ -coverage: 95.45%coverage95.45% \ No newline at end of file +coverage: 67.27%coverage67.27% \ No newline at end of file diff --git a/docs/badges/tests-badge.svg b/docs/badges/tests-badge.svg index aefefb0..cd16718 100644 --- a/docs/badges/tests-badge.svg +++ b/docs/badges/tests-badge.svg @@ -1 +1 @@ -tests: 30tests30 \ No newline at end of file +tests: 34tests34 \ No newline at end of file diff --git a/notebooks/data/itc_binding_expt.csv b/notebooks/data/itc_binding_expt.csv new file mode 100644 index 0000000..a2a84f9 --- /dev/null +++ b/notebooks/data/itc_binding_expt.csv @@ -0,0 +1,27 @@ +injection,heat +0.0, +2.0,-0.6698887856953665 +2.0,-0.6653981051510617 +2.0,-0.6628770104848354 +2.0,-0.6572600039805307 +2.0,-0.6544483711885344 +2.0,-0.6504849636862378 +2.0,-0.6404583989405751 +2.0,-0.6376838389904914 +2.0,-0.6378359001575715 +2.0,-0.633540956451369 +2.0,-0.6251375384830915 +2.0,-0.6201433401680164 +2.0,-0.6151452055627816 +2.0,-0.5484958725734232 +2.0,-0.2920939813000814 +2.0,-0.23494590560590042 +2.0,-0.22694817238908618 +2.0,-0.22704683549278215 +2.0,-0.2229765373934299 +2.0,-0.22315231943129848 +2.0,-0.2261348200467626 +2.0,-0.22047538531018618 +2.0,-0.21948399323774065 +2.0,-0.21865938338939592 +2.0,-0.2160287541946412 diff --git a/notebooks/data/itc_blank_expt.csv b/notebooks/data/itc_blank_expt.csv new file mode 100644 index 0000000..0c60f8a --- /dev/null +++ b/notebooks/data/itc_blank_expt.csv @@ -0,0 +1,27 @@ +injection,heat +0.0, +2.0,-0.2442462588685921 +2.0,-0.24295005228246766 +2.0,-0.23557114377762883 +2.0,-0.23844502898873843 +2.0,-0.23933754638183913 +2.0,-0.2443435490673292 +2.0,-0.23589295931746368 +2.0,-0.2380656119509871 +2.0,-0.2330682723652203 +2.0,-0.2279854541512425 +2.0,-0.23190528384682552 +2.0,-0.23464743869038096 +2.0,-0.2366097006847176 +2.0,-0.22320395204965413 +2.0,-0.22823351798594146 +2.0,-0.2300511120307936 +2.0,-0.2209894117300196 +2.0,-0.21866333693069204 +2.0,-0.223161934647072 +2.0,-0.21805199016761126 +2.0,-0.21495030878756455 +2.0,-0.2142776639631268 +2.0,-0.20871828135605286 +2.0,-0.2174045643244037 +2.0,-0.21417738451534674 diff --git a/notebooks/global-fit.ipynb b/notebooks/global-fit.ipynb new file mode 100644 index 0000000..d5e5f32 --- /dev/null +++ b/notebooks/global-fit.ipynb @@ -0,0 +1,381 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "b11cea11-6bb7-4286-9550-6a47f3c017ad", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "from matplotlib import pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "import dataprob\n", + "import copy\n", + "\n", + "import linkage\n" + ] + }, + { + "cell_type": "markdown", + "id": "b8a4d8a8-adcf-4dfe-9ec7-5567ab6551e4", + "metadata": {}, + "source": [ + "#### Load experimental data" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "75839bf7-0265-4c1b-9bdb-770c1d2fb2f1", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "blank = linkage.experiment.Experiment(\"data/itc_blank_expt.csv\",\n", + " cell_contents={},\n", + " syringe_contents={\"ET\":5e-3},\n", + " cell_volume=280)\n", + "blank.define_itc_observable(obs_column=\"heat\",\n", + " obs_stdev=0.01)\n", + "\n", + "binding = linkage.experiment.Experiment(\"data/itc_binding_expt.csv\",\n", + " cell_contents={\"CT\":0.5e-3},\n", + " syringe_contents={\"ET\":5e-3},\n", + " cell_volume=280)\n", + "binding.define_itc_observable(obs_column=\"heat\",\n", + " obs_stdev=0.01)\n" + ] + }, + { + "cell_type": "markdown", + "id": "47cb7093-8e36-4d30-99b8-174cd98964ac", + "metadata": {}, + "source": [ + "#### Create a linkage model" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "973ecc70-baf0-4fc2-a25a-047d67b0da51", + "metadata": {}, + "outputs": [], + "source": [ + "expt_list = [blank,binding] \n", + "\n", + "gm = linkage.GlobalModel(model_name=\"CaEDTA\",\n", + " expt_list=expt_list)" + ] + }, + { + "cell_type": "markdown", + "id": "bda19ab6-4db2-47c3-83d7-3c8486f3a1f2", + "metadata": {}, + "source": [ + "#### Plot data" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "e82c93f3-c3f8-44c9-b1a8-73f6b86ee6fe", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0, 0.5, 'heat')" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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OnXqBBsbGwQFBWm5O0RERPQvhSKMAEBwcDB8fHzg7++PoKAgNG7cGMuXL89anpaWhoiICCQlJQEAihUrhsOHDyMoKAje3t545513YG9vj99++031KZtERERU8ArFPCNa4jwjREREuWPqObTQ9IwQERFR0cQwQkRERJpiGCEiIiJNMYwQERGRphhGiIiISFMMI0RERKQphhEiIiLSFMMIERERaYphhIiIiDTFMEJERESaYhghIiIiTTGMEBERkaYYRoiIiEhTDCNERESkKYYRIiIi0hTDCBEREWmKYYSIiIg0xTBCREREmmIYISIiIk0xjBAREZGmGEaIiIhIUwwjREREpCmGESIiItIUwwgRERFpimGEiIiINMUwQkRERJpiGCEiIiJNMYwQERGRphhGiIiISFMMI0RERKQphhEiIiLSFMMIERERaYphhIiIiDTFMEJERESaYhghIiIiTTGMEBERkaYYRoiIiEhTDCNERESkKYYRIiIi0hTDCBEREWmKYYSIiIg0xTBCREREmmIYISIiIk0xjBAREZGmGEaIiIhIUwwjREREpCmGESIiItIUwwgRERFpimGEiIiINMUwQkRERJpiGCEiIiJNMYwQERGRphhGiIiISFMMI0RERKQphhEiIiLSFMMIERERaYphhIiIiDTFMEJERESaYhghIiIiTTGMEBERkaYYRoiIiEhTDCNERESkKYYRIiIi0hTDCBEREWmKYYSIiIg0xTBCREREmmIYISIiIk0xjBAREZGmGEaIiIhIUwwjREREpCmGESIiItIUwwgRERFpimGEiIiINMUwQkRERJpiGCEiIiJNMYwQERGRphhGiIiISFMMI0RERKQphhEiIiLSFMMIERERaarQhJG4uDh0794dDg4OcHJyQt++fZGYmGjSuiKC1q1bQ6fT4aeffsrfQomIiOipFJow0r17d5w7dw579uzB9u3bcejQIQwYMMCkdefPnw+dTpfPFRIREVFuWGhdgCnOnz+PXbt24fjx4/D19QUALFy4EEFBQZgzZw48PDxU1w0PD8fcuXPxxx9/wN3dvaBKJiIiIhMVip6R0NBQODk5ZQURAAgICICZmRnCwsJU10tKSkK3bt2wePFiuLm5mfReKSkpSEhIyPZDRERE+adQhJGYmBi4urpme83CwgLOzs6IiYlRXe/DDz/Eq6++irZt25r8XtOnT4ejo2PWT5kyZXJdNxERERmnaRgZO3YsdDqdwZ8LFy7katshISHYt28f5s+f/1TrjRs3DvHx8Vk/0dHRuXp/IiIiMo2mY0ZGjRqFXr16GWzj5eUFNzc3xMbGZns9PT0dcXFxqpdf9u3bh6ioKDg5OWV7vUOHDnjttddw4MCBHNeztraGtbW1qbtAREREz0jTMOLi4gIXFxej7Ro2bIgHDx7gxIkTqFevHgAlbOj1evj5+eW4ztixY9GvX79sr9WsWRPz5s1DmzZtnr14IiIiyhOF4m6aqlWrolWrVujfvz+WLVuGtLQ0DB06FF26dMm6k+bmzZvw9/fH2rVr0aBBA7i5ueXYa1K2bFlUqFChoHeBiIiIVBSKAawAEBwcDB8fH/j7+yMoKAiNGzfG8uXLs5anpaUhIiICSUlJGlZJRERET0snIqJ1Ec+zhIQEODo6Ij4+Hg4ODlqXQ0REVGiYeg4tND0jREREVDQxjBAREZGmGEaIiIhIUwwjREREpCmGESIiItIUwwgRERFpimGEiIiINMUwQkRERJpiGCEiIiJNMYwQERGRphhGiIiISFMMI0RERKQphhEiIiLSFMMIERERaYphhIiIiDTFMEJERESaYhghIiIiTeUqjJibmyM2NvaJ1+/duwdzc/NnLoqIiIheHLkKIyKS4+spKSmwsrJ6poKIiIjoxWLxNI0XLFgAANDpdFi5ciXs7OyylmVkZODQoUPw8fHJ2wqJiIioSHuqMDJv3jwASs/IsmXLsl2SsbKyQvny5bFs2bK8rZCIiIiKtKcKI1euXAEANG/eHJs3b0aJEiXypSgiIiJ6cTxVGMm0f//+vK6DiIiIXlC5CiMAcOPGDYSEhOD69etITU3NtuzLL7985sKIiIjoxZCrMLJ371689dZb8PLywoULF1CjRg1cvXoVIoK6devmdY1ERERUhOXq1t5x48bho48+wpkzZ1CsWDFs2rQJ0dHRaNq0KTp16pTXNRIREVERlqswcv78ebz33nsAAAsLCzx+/Bh2dnb47LPPMHPmzDwtkIiIiIq2XIWR4sWLZ40TcXd3R1RUVNayu3fv5k1lRERE9ELI1ZiRV155BUeOHEHVqlURFBSEUaNG4cyZM9i8eTNeeeWVvK6RiIiIirBchZEvv/wSiYmJAIApU6YgMTER33//PSpVqsQ7aYiIiOip6ETtQTMEAEhISICjoyPi4+Ph4OCgdTlERESFhqnn0FyNGQGABw8eYOXKlRg3bhzi4uIAACdPnsTNmzdzu0kiIiJ6AeXqMs3p06cREBAAR0dHXL16Ff3794ezszM2b96M69evY+3atXldJxERERVRueoZGTlyJHr16oVLly6hWLFiWa8HBQXh0KFDeVYcERERFX25CiPHjx/HwIEDn3jd09MTMTExz1wUERERvThyFUasra2RkJDwxOsXL16Ei4vLMxdFREREL45chZG33noLn332GdLS0gAAOp0O169fx8cff4wOHTrkaYFERERUtOUqjMydOxeJiYlwdXXF48eP0bRpU3h7e8POzg7Tpk3L6xqJiIioCMvV3TSOjo7Ys2cPjh49ij///BOJiYmoW7cuAgIC8ro+IiIiKuJyPenZ3r17sXfvXsTGxkKv12dbtmrVqjwp7nnASc+IiIhyx9RzaK56RqZMmYLPPvsMvr6+cHd3h06ny3WhRERE9GLLVRhZtmwZ1qxZg3fffTev6yEiIqIXTK4GsKampuLVV1/N61qIiIjoBZSrMNKvXz+sW7cur2shIiKiF5DJl2lGjhyZ9We9Xo/ly5fj119/Ra1atWBpaZmt7Zdffpl3FRIREVGRZnIYOXXqVLbf69SpAwA4e/Zsttc5mJWIiIiehslhZP/+/flZBxEREb2gcjVmhIiIiCivMIwQERGRphhGiIiISFMMI0RERKQphhEiIiLSFMMIERERaYphhIiIiDTFMEJERESaYhghIiIiTTGMEBERkaYYRoiIiEhTDCNERESkKYYRIiIi0hTDCBEREWmKYYSIiIg0xTBCREREmmIYISIiIk0xjBAREZGmGEaIiIhIUwwjREREpCmGESIiItIUwwgRERFpimGEiIiINMUwQkRERJpiGCEiIiJNMYwQERGRphhGiIiISFMMI0RERKQphhEiIiLSFMMIERERaYphhIiIiDTFMEJERESaYhghIiIiTRWaMBIXF4fu3bvDwcEBTk5O6Nu3LxITEw2u06xZM+h0umw/77//fgFVTERERKaw0LoAU3Xv3h23b9/Gnj17kJaWht69e2PAgAFYt26dwfX69++Pzz77LOt3W1vb/C6ViIiInkKhCCPnz5/Hrl27cPz4cfj6+gIAFi5ciKCgIMyZMwceHh6q69ra2sLNza2gSiUiIqKnVCgu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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "style = {\"s\":50,\n", + " \"facecolor\":\"none\",\n", + " \"edgecolor\":\"black\"}\n", + "\n", + "color_order = [\"red\",\"black\"]\n", + "fig, ax = plt.subplots(1,figsize=(6,6))\n", + "for i in range(len(gm._expt_list)):\n", + " style[\"edgecolor\"] = color_order[i]\n", + " ax.scatter(np.arange(len(gm._expt_list[i].expt_data[\"heat\"])),\n", + " gm._expt_list[i].expt_data[\"heat\"],**style)\n", + "plt.xlabel(\"injection\")\n", + "plt.ylabel(\"heat\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "293deeb5-170a-4b1d-9261-8366c78b2423", + "metadata": {}, + "source": [ + "#### Do fit" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "f09830f6-3078-45bd-97eb-e82b4204556e", + "metadata": {}, + "outputs": [], + "source": [ + "#BayesianFitter does a Bayesian sampling rather than maximum likelihood fit\n", + "\n", + "F = dataprob.MLFitter()\n", + "#F = dataprob.BayesianFitter()\n", + "F.fit(model=gm.model_normalized,\n", + " guesses=[5,-11000,0,0],\n", + " names=gm.parameter_names,\n", + " y_obs=gm.y_obs_normalized,\n", + " y_stdev=gm.y_stdev_normalized)" + ] + }, + { + "cell_type": "markdown", + "id": "1987676f-1c6a-44a3-995e-44af42226172", + "metadata": {}, + "source": [ + "#### Plot results" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "a6680df0-9b17-40fe-89c2-b9d6b6b110a1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
paramestimatestdevlow_95high_95guesslower_boundupper_bound
0KE6.9711770.0872646.7954187.1469365.0-infinf
1dH_E-11949.66040597.575492-12146.187535-11753.133275-11000.0-infinf
2nuisance_dil_CT-0.6829056.055914-12.88014111.5143310.0-infinf
3nuisance_dil_ET-49.8415840.308075-50.462079-49.2210890.0-infinf
\n", + "
" + ], + "text/plain": [ + " param estimate stdev low_95 high_95 \\\n", + "0 KE 6.971177 0.087264 6.795418 7.146936 \n", + "1 dH_E -11949.660405 97.575492 -12146.187535 -11753.133275 \n", + "2 nuisance_dil_CT -0.682905 6.055914 -12.880141 11.514331 \n", + "3 nuisance_dil_ET -49.841584 0.308075 -50.462079 -49.221089 \n", + "\n", + " guess lower_bound upper_bound \n", + "0 5.0 -inf inf \n", + "1 -11000.0 -inf inf \n", + "2 0.0 -inf inf \n", + "3 0.0 -inf inf " + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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wtraGra2tujXrx/i4+Oz3P/OnTtQKBSZPtavX1+ANSciIiJ9ojfhyNfXF5cvX8aePXuwfft2HD58GAMHDsxy/1KlSqnuZaZ8TJkyBZaWlmjfvn0B1pyIiIj0iUIIIXRdieyEhoaiatWqOH36NOrWrQsACAoKgo+PD+7fvw8XFxeNyqlTpw48PT3x66+/avzZebmrLxEREelGXq7fetFydOLECdja2qqCEQC0atUKBgYGOHnypEZlBAcH49y5c+jXr5/a/RITExEbG5vhQURERO8OvQhHkZGRcHR0zLDNyMgI9vb2iIyM1KiMX3/9FR4eHmjcuLHa/aZPnw4bGxvVo1SpUrmuNxEREekfnYajcePGZTloWvm4evVqnj8nISEBa9asybbVCADGjx+PmJgY1ePevXt5/nwiIiLSH0a6/PCRI0eid+/eavcpX748nJycEBUVlWF7SkoKoqOj4eTklO3nbNiwAS9evECvXr2y3dfU1BSmpqaq58ohWexeIyIi0h/K63ZuhlbrNBw5ODjAwcEh2/0aNWqEZ8+eITg4GF5eXgCA/fv3Iy0tDQ0aNMj2/b/++is6duyo0We9KS4uDgDYvUZERKSH4uLiYGNjk6P36MVsNQBo3749Hj58iMWLFyM5ORl9+vRB3bp1sWbNGgDAgwcP4O3tjZUrV6J+/fqq9924cQOVK1fGjh070K5duxx/blpaGsLDw2FlZQWFQqG144mNjUWpUqVw7949zoIrQDzvusHzrhs877rB864bb553IQTi4uLg4uICA4OcjSLSactRTqxevRr+/v7w9vaGgYEBunTpgnnz5qleT05ORlhYGF68eJHhfb/99hvc3NzQpk2bXH2ugYEB3Nzc8lR3daytrfmPRwd43nWD5103eN51g+ddN9Kf95y2GCnpTctRUcP1k3SD5103eN51g+ddN3jedUOb510vpvITERERFRSGIx0xNTVFYGBghplxlP943nWD5103eN51g+ddN7R53tmtRkRERJQOW46IiIiI0mE4IiIiIkqH4YiIiIgoHYYjIiIionQYjnRkwYIFKFu2LMzMzNCgQQOcOnVK11Uq0iZPnvzWTY3d3d11Xa0i5/Dhw+jQoQNcXFygUCiwefPmDK8LIfDNN9/A2dkZ5ubmaNWqFa5fv66byhYh2Z333r17v/X9z80dA+i16dOno169erCy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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "df = gm.as_df\n", + "\n", + "style = {\"s\":50,\n", + " \"facecolor\":\"none\",\n", + " \"edgecolor\":\"black\"}\n", + "color_order = [\"red\",\"black\"]\n", + "\n", + "for expt in np.unique(df[\"expt_id\"]):\n", + " this_df = df.loc[df[\"expt_id\"] == expt,:]\n", + "\n", + " x = np.arange(len(this_df))\n", + "\n", + " style[\"edgecolor\"] = color_order[expt]\n", + " plt.scatter(x,this_df[\"y_obs\"],**style)\n", + " plt.errorbar(x=x,\n", + " y=this_df[\"y_obs\"],\n", + " yerr=this_df[\"y_stdev\"],\n", + " ls=\"none\",\n", + " lw=1,\n", + " capsize=3,\n", + " color=color_order[expt])\n", + " plt.plot(np.arange(len(this_df)),\n", + " this_df[\"y_calc\"],\n", + " '-',\n", + " lw=2,\n", + " color=color_order[expt])\n", + "plt.xlabel(\"injection\")\n", + "plt.ylabel(\"heat\")\n", + "\n", + "F.fit_to_df" + ] + }, + { + "cell_type": "markdown", + "id": "05c00ad5-e78d-473d-9b75-912a24b41f63", + "metadata": {}, + "source": [ + "#### Corner plot to look for parameter correlations" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "7e403511-ccb0-4181-9e3a-efa381aacf6a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "not doing corner plot for parameter nuisance_dil_CT\n", + "not doing corner plot for parameter nuisance_dil_ET\n" + ] + }, + { + "data": { + "image/png": "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zp00Njaq573uuut4+OGHWb9+PWvXrlX9Ft6prVu38rvf/Q6A2267Td2ez+f53//9XwA1g5HP5ykUCmQyGQqFgmrpnM1mKSkpYXBwkPnz5+NyuWhtbVXHIuUUgxBiOpiyMwj6tPSyZcuYP38+3/ve90ilUur++vp6br/9diwWC8899xww8gsfkHBwFOhBQS+MpO83yGazFAoF/H6/mqoHVMDTN73qAoEAn/jEJ4CRWYR3I51Oc8cdd6BpGhdeeCEnnHCCuu/1118nFAphMBhU3QOj0YjFYsFoNKqqjy0tLWzfvp3XXnuN9evX88Ybb9DX10c+n1dLKbp4PK6WUg7kUB4rhBBHw5QLCPq0tH6xr6ys5H3vex9//vOf+eMf/6juNxgMnHnmmSQSCV5+eaSznwSDI6evr49du3axbt06WlpaipYaAoEAxx13HI2NjcyYMQOv14vL5cJgMKh6CDD2JIPuhhtuwGq18vLLL/OrX/3qHY1vaGiIq666ihdffBGbzcatt9465v7HH38c2LO8oBdwslgsOJ1OLBYL0WiUSCRCPB7HarWSSCTGhM7q6uoxzznessu+HMpjhRDiaJhSAWHr1q18/vOf5/zzz+eWW27hueeew2azce+99+LxeLj//vv55S9/OWateu7cuWq6WxxZyWSScDjMli1b2Lx5s9qwOGvWLPL5PHa7XVVadDgc2O12zGYzVqtVhbe//e1vRacTqqqquOGGGwD44he/yG9+85tDGld7Rzsf+chHePHFF3G5XPzsZz9TbZkBXn31VR577DFgbHllfYlB37eij91iseD1elm6dCnBYJDy8nIaGhrGtLGG4n0a+3MojxVCiKNhygSEjRs3cuqpp5LJZKiurqalpYV///d/Z9euXbjdbh5//HFqamr4wQ9+wEc+8hFWr17N9ddfz9q1a7n44osnevjTnn6RDAQCaJpGoVBQm/Z2796NpmkMDAxgNBrJZrNEo1FMJhMlJSXYbDYsFgsGg4H+/n6effbZouf/yle+wtVXX42maXzhC1/gmWeeOeixXXH55ezYsYOqqioef/xxzjjjDHVfKpXitttuG7MfAkaCgr7s4Xa71TFGh8OBz+fDZDIRCARYsGCBqgGxdxVFPSAdbEA42McKIcTRMCUCQnd3N1dffTWf+tSnePjhh/nP//xPvvjFL9Le3q52vbvdbn75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oRyzJvvP48GaLl+HGEt6MUxjv/jFL9ixYwff/OY3yefzXH755SokTMYmOBs3buTMM8/kgx/8IFarlWeeeYavfOUrrFq1CmDSjrulpYX//d//Zdu2bVx44YWcfPLJlJWVTfSw9uutt97irLPO4pOf/CRLliyhtLR00v79TidtbW08//zzDA0NsWzZMhYsWDAl/86ny9exbds2fvvb39Le3s55553HwoULmT9//kQP65Ac0a9BE9PWHXfcoZ122mnaTTfdpDU1NWm//vWv1X25XG4CR1ZsaGhIW7p0qXbLLbdomqZpqVRK++xnP6vdcccdEzuwA3jrrbe0GTNmaOeee6524oknah6PR3vwwQc1TdO0fD4/waMbX3t7u9bQ0KB96UtfGnN7JpOZoBEdG9566y0tGAxqJ554ojZ79mzNarVq/+///T/trbfemuihHZLp8nVs3LhR8/v92nnnnactW7ZMKy8v18477zztsccem+ihHbQj/TVIQJjGnn76ae3mm2/Wtm7dqn3iE5/QFixYoP3973/XvvWtb2kvvPCCVigUJnqIyvbt27X58+dr69atU7ddf/312imnnKJdcMEF2iWXXKJ1dnZqmqZNmnG3trZqc+bM0W6//XYtm81qmqZp3/nOd7RAIKD19/dP8Oj27Xe/+5125plnapqmadlsVvva176mffjDH9ZWrlyp/epXv5rg0U1Pw8PD2qmnnqp96Utf0uLxuFYoFLSf/OQn2pw5c7SVK1dqr7766kQP8aBMl68jnU5ry5cv16677joV5NeuXatdeeWV2nHHHaf953/+5wSP8MCOxtcgi7vTmNVq5cknn6Suro4vf/nLnHXWWVxxxRV8/etfZ86cOZNqT4LX6yWdTvPjH/+Y/v5+7rjjDv7zP/+TD37wg5x//vn09vZy7rnnks1mJ8VUZj6f5w9/+AOLFy/mC1/4gtonsXLlSrxeL729vRM8wn3bunWrqvN+9tln8+qrrxIMBtE0jU984hPcf//9EzzC6WlgYIBFixbhdDoxGAxcf/31rFq1ig0bNrB69Wp279490UM8KNPh6zAajbS0tODxeNTP7hlnnMGXvvQlTjnlFH74wx/yt7/9bYJHuX9H42uQgDCNLViwAL/fj8Xy/9u79+iazvQP4N+TeyK3JkTc4hY5KmJEhIy6TybilhJq2lKNoXVtRt0TLO1o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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "_ = F.corner_plot(filter_params=\"nuisance\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6ffe58ee-d894-4cb5-9d91-a261a9d9e48a", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d72d8bfd-d925-445e-967d-4f6603621a2d", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/reports/flake.txt b/reports/flake.txt index 4acabfa..46ed83b 100644 --- a/reports/flake.txt +++ b/reports/flake.txt @@ -32,38 +32,70 @@ ./build/lib/linkage/experiment/baseline_corrector.py:43:18: E231 missing whitespace after ',' ./build/lib/linkage/experiment/baseline_corrector.py:43:45: E231 missing whitespace after ',' ./build/lib/linkage/experiment/baseline_corrector.py:43:49: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:9:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/experiment/experiment.py:18:26: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:21:38: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:23:38: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:26:38: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:26:47: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:37:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experiment.py:48:60: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:51:5: E303 too many blank lines (2) +./build/lib/linkage/experiment/experiment.py:10:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/experiment/experiment.py:19:26: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:22:38: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:24:38: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:27:38: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:27:47: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:38:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:49:60: E231 missing whitespace after ',' ./build/lib/linkage/experiment/experiment.py:51:87: W291 trailing whitespace ./build/lib/linkage/experiment/experiment.py:53:55: E231 missing whitespace after ',' ./build/lib/linkage/experiment/experiment.py:53:68: E231 missing whitespace after ',' ./build/lib/linkage/experiment/experiment.py:54:27: E231 missing whitespace after ',' ./build/lib/linkage/experiment/experiment.py:58:39: E231 missing whitespace after ',' ./build/lib/linkage/experiment/experiment.py:58:50: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:76:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experiment.py:90:43: W291 trailing whitespace -./build/lib/linkage/experiment/experiment.py:98:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experiment.py:113:35: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:118:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experiment.py:123:51: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:126:46: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:129:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experiment.py:140:53: E231 missing whitespace after ':' -./build/lib/linkage/experiment/experiment.py:141:63: E231 missing whitespace after ':' -./build/lib/linkage/experiment/experiment.py:142:56: E231 missing whitespace after ':' +./build/lib/linkage/experiment/experiment.py:74:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:78:79: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:79:77: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:82:75: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:86:43: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:89:74: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:92:76: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:93:74: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:94:32: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:97:75: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:98:50: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:104:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:118:43: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:131:76: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:133:34: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:135:1: W293 blank line contains whitespace ./build/lib/linkage/experiment/experiment.py:143:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experiment.py:144:34: E231 missing whitespace after ',' -./build/lib/linkage/experiment/experiment.py:144:45: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:149:1: W293 blank line contains whitespace ./build/lib/linkage/experiment/experiment.py:155:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experiment.py:171:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/experiment.py:174:43: W292 no newline at end of file +./build/lib/linkage/experiment/experiment.py:156:34: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:162:49: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:164:42: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:172:54: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:173:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:178:24: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:182:65: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:187:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:188:48: E231 missing whitespace after ':' +./build/lib/linkage/experiment/experiment.py:189:56: E231 missing whitespace after ':' +./build/lib/linkage/experiment/experiment.py:192:5: E303 too many blank lines (2) +./build/lib/linkage/experiment/experiment.py:198:63: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:199:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:204:24: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:208:65: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:210:78: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:211:39: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:219:76: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:225:77: W291 trailing whitespace +./build/lib/linkage/experiment/experiment.py:231:45: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:234:40: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:244:48: E231 missing whitespace after ':' +./build/lib/linkage/experiment/experiment.py:245:56: E231 missing whitespace after ':' +./build/lib/linkage/experiment/experiment.py:246:56: E231 missing whitespace after ':' +./build/lib/linkage/experiment/experiment.py:247:56: E231 missing whitespace after ':' +./build/lib/linkage/experiment/experiment.py:248:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:249:34: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:249:45: E231 missing whitespace after ',' +./build/lib/linkage/experiment/experiment.py:260:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:276:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/experiment.py:279:43: W292 no newline at end of file ./build/lib/linkage/experiment/experimental_point.py:3:1: E302 expected 2 blank lines, found 1 ./build/lib/linkage/experiment/experimental_point.py:6:13: W291 trailing whitespace ./build/lib/linkage/experiment/experimental_point.py:8:1: W293 blank line contains whitespace @@ -123,12 +155,19 @@ ./build/lib/linkage/experiment/point/itc_point.py:80:41: E231 missing whitespace after ',' ./build/lib/linkage/experiment/point/itc_point.py:84:17: W291 trailing whitespace ./build/lib/linkage/experiment/point/itc_point.py:93:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/point/itc_point.py:97:20: E221 multiple spaces before operator -./build/lib/linkage/experiment/point/itc_point.py:97:51: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/itc_point.py:97:74: W291 trailing whitespace ./build/lib/linkage/experiment/point/itc_point.py:98:53: E231 missing whitespace after ',' -./build/lib/linkage/experiment/point/itc_point.py:103:32: W291 trailing whitespace -./build/lib/linkage/experiment/point/itc_point.py:105:71: E231 missing whitespace after ',' -./build/lib/linkage/experiment/point/itc_point.py:107:26: W292 no newline at end of file +./build/lib/linkage/experiment/point/itc_point.py:101:20: E221 multiple spaces before operator +./build/lib/linkage/experiment/point/itc_point.py:101:51: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/itc_point.py:102:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/point/itc_point.py:103:72: W291 trailing whitespace +./build/lib/linkage/experiment/point/itc_point.py:104:42: W291 trailing whitespace +./build/lib/linkage/experiment/point/itc_point.py:107:73: W291 trailing whitespace +./build/lib/linkage/experiment/point/itc_point.py:109:78: W291 trailing whitespace +./build/lib/linkage/experiment/point/itc_point.py:110:71: W291 trailing whitespace +./build/lib/linkage/experiment/point/itc_point.py:115:32: W291 trailing whitespace +./build/lib/linkage/experiment/point/itc_point.py:117:71: E231 missing whitespace after ',' +./build/lib/linkage/experiment/point/itc_point.py:119:26: W292 no newline at end of file ./build/lib/linkage/experiment/point/spec_point.py:6:1: E302 expected 2 blank lines, found 1 ./build/lib/linkage/experiment/point/spec_point.py:8:66: W291 trailing whitespace ./build/lib/linkage/experiment/point/spec_point.py:9:67: W291 trailing whitespace @@ -156,33 +195,36 @@ ./build/lib/linkage/experiment/point/test_itc_point.py:40:1: W293 blank line contains whitespace ./build/lib/linkage/experiment/point/test_itc_point.py:46:1: W391 blank line at end of file ./build/lib/linkage/experiment/titrator.py:6:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/experiment/titrator.py:8:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:9:42: E231 missing whitespace after ',' -./build/lib/linkage/experiment/titrator.py:13:45: E231 missing whitespace after ',' -./build/lib/linkage/experiment/titrator.py:20:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:25:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:36:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/experiment/titrator.py:54:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:63:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/experiment/titrator.py:68:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:81:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:91:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:99:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:102:1: E303 too many blank lines (3) -./build/lib/linkage/experiment/titrator.py:109:55: W291 trailing whitespace -./build/lib/linkage/experiment/titrator.py:110:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:117:32: W291 trailing whitespace -./build/lib/linkage/experiment/titrator.py:122:32: W291 trailing whitespace -./build/lib/linkage/experiment/titrator.py:127:51: W291 trailing whitespace -./build/lib/linkage/experiment/titrator.py:129:90: W291 trailing whitespace -./build/lib/linkage/experiment/titrator.py:130:67: W291 trailing whitespace -./build/lib/linkage/experiment/titrator.py:131:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:141:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:143:47: E231 missing whitespace after ',' -./build/lib/linkage/experiment/titrator.py:144:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:152:1: W293 blank line contains whitespace -./build/lib/linkage/experiment/titrator.py:154:5: E303 too many blank lines (2) -./build/lib/linkage/experiment/titrator.py:166:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:9:79: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:16:74: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:18:77: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:19:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:23:40: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:29:42: E231 missing whitespace after ',' +./build/lib/linkage/experiment/titrator.py:33:45: E231 missing whitespace after ',' +./build/lib/linkage/experiment/titrator.py:40:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:45:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:56:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/experiment/titrator.py:74:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:83:1: E302 expected 2 blank lines, found 1 +./build/lib/linkage/experiment/titrator.py:88:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:98:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:117:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:120:1: E303 too many blank lines (3) +./build/lib/linkage/experiment/titrator.py:127:55: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:128:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:135:32: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:140:32: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:145:51: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:147:90: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:148:67: W291 trailing whitespace +./build/lib/linkage/experiment/titrator.py:149:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:160:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:162:47: E231 missing whitespace after ',' +./build/lib/linkage/experiment/titrator.py:163:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:171:1: W293 blank line contains whitespace +./build/lib/linkage/experiment/titrator.py:173:5: E303 too many blank lines (2) +./build/lib/linkage/experiment/titrator.py:185:1: W293 blank line contains whitespace ./build/lib/linkage/models/__init__.py:2:1: F401 'linkage.models.six_state_edta.SixStateEDTA' imported but unused ./build/lib/linkage/models/__init__.py:3:1: F401 'linkage.models.ca_edta.CaEDTA' imported but unused ./build/lib/linkage/models/base.py:7:1: E302 expected 2 blank lines, found 1 @@ -296,8 +338,6 @@ ./build/lib/linkage/models/ca_edta.py:39:33: E231 missing whitespace after ',' ./build/lib/linkage/models/ca_edta.py:47:30: E231 missing whitespace after ',' ./build/lib/linkage/models/ca_edta.py:48:1: W293 blank line contains whitespace -./build/lib/linkage/models/ca_edta.py:52:1: W293 blank line contains whitespace -./build/lib/linkage/models/ca_edta.py:55:13: W292 no newline at end of file ./build/lib/linkage/models/six_state_edta.py:25:25: E231 missing whitespace after ',' ./build/lib/linkage/models/six_state_edta.py:25:28: E231 missing whitespace after ',' ./build/lib/linkage/models/six_state_edta.py:25:31: E231 missing whitespace after ',' @@ -345,16 +385,15 @@ ./build/lib/linkage/models/six_state_edta.py:99:9: E741 ambiguous variable name 'I' ./build/lib/linkage/models/six_state_edta.py:105:1: W293 blank line contains whitespace ./build/lib/linkage/models/six_state_edta.py:107:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:110:5: E303 too many blank lines (3) -./build/lib/linkage/models/six_state_edta.py:112:30: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:112:35: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:112:40: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:112:45: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:112:50: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:116:30: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:116:35: E231 missing whitespace after ',' -./build/lib/linkage/models/six_state_edta.py:117:1: W293 blank line contains whitespace -./build/lib/linkage/models/six_state_edta.py:121:1: W391 blank line at end of file +./build/lib/linkage/models/six_state_edta.py:110:30: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:110:35: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:110:40: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:110:45: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:110:50: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:114:30: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:114:35: E231 missing whitespace after ',' +./build/lib/linkage/models/six_state_edta.py:115:1: W293 blank line contains whitespace +./build/lib/linkage/models/six_state_edta.py:119:1: W391 blank line at end of file ./build/lib/linkage/organizer/__init__.py:1:1: F401 'linkage.organizer.global_model.GlobalModel' imported but unused ./build/lib/linkage/organizer/__init__.py:1:55: W292 no newline at end of file ./build/lib/linkage/organizer/global_fit.py:10:1: E302 expected 2 blank lines, found 1 @@ -432,89 +471,124 @@ ./build/lib/linkage/organizer/global_fit.py:337:1: W293 blank line contains whitespace ./build/lib/linkage/organizer/global_fit.py:337:9: W292 no newline at end of file ./build/lib/linkage/organizer/global_model.py:10:1: E302 expected 2 blank lines, found 1 -./build/lib/linkage/organizer/global_model.py:17:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:35:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:42:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:53:61: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:55:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:61:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:62:59: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:64:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:65:58: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:72:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:78:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:86:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:91:77: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:93:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:103:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:104:47: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:119:41: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:126:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:129:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:135:27: E225 missing whitespace around operator -./build/lib/linkage/organizer/global_model.py:158:68: E221 multiple spaces before operator -./build/lib/linkage/organizer/global_model.py:159:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:161:5: E303 too many blank lines (2) -./build/lib/linkage/organizer/global_model.py:163:69: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:166:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:172:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:175:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:176:61: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:177:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:180:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:191:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:196:49: E127 continuation line over-indented for visual indent -./build/lib/linkage/organizer/global_model.py:197:48: E127 continuation line over-indented for visual indent -./build/lib/linkage/organizer/global_model.py:200:57: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:204:78: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:205:23: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:212:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:213:53: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:215:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:217:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:219:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:19:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:45:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:57:61: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:59:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:65:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:66:59: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:68:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:69:58: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:76:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:82:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:90:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:95:77: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:97:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:107:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:108:47: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:123:41: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:130:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:133:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:135:77: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:136:78: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:138:72: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:141:77: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:142:74: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:143:78: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:146:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:162:79: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:163:47: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:178:68: E221 multiple spaces before operator +./build/lib/linkage/organizer/global_model.py:179:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:181:5: E303 too many blank lines (2) +./build/lib/linkage/organizer/global_model.py:183:69: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:186:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:192:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:195:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:196:61: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:197:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:200:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:203:79: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:204:75: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:206:73: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:207:78: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:208:52: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:211:81: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:212:34: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:216:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:218:58: E231 missing whitespace after ',' ./build/lib/linkage/organizer/global_model.py:221:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:222:75: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:223:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:226:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:225:76: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:226:19: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:229:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:231:1: W293 blank line contains whitespace ./build/lib/linkage/organizer/global_model.py:240:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:245:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:257:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:262:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:267:48: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:271:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:272:5: E303 too many blank lines (2) -./build/lib/linkage/organizer/global_model.py:272:19: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:245:5: E303 too many blank lines (2) +./build/lib/linkage/organizer/global_model.py:245:24: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:245:34: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:245:43: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:250:71: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:251:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:254:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:266:48: E127 continuation line over-indented for visual indent +./build/lib/linkage/organizer/global_model.py:268:1: W293 blank line contains whitespace ./build/lib/linkage/organizer/global_model.py:273:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:276:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:288:78: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:290:59: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:293:56: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:294:53: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:297:40: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:304:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:313:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:334:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:341:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:348:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:352:75: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:353:15: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:356:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:360:75: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:361:15: W291 trailing whitespace -./build/lib/linkage/organizer/global_model.py:364:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:368:25: E231 missing whitespace after ':' -./build/lib/linkage/organizer/global_model.py:369:27: E231 missing whitespace after ':' -./build/lib/linkage/organizer/global_model.py:370:26: E231 missing whitespace after ':' +./build/lib/linkage/organizer/global_model.py:307:5: E303 too many blank lines (2) +./build/lib/linkage/organizer/global_model.py:328:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:332:14: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:335:49: E127 continuation line over-indented for visual indent +./build/lib/linkage/organizer/global_model.py:336:48: E127 continuation line over-indented for visual indent +./build/lib/linkage/organizer/global_model.py:339:57: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:343:78: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:350:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:351:51: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:354:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:365:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:372:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:377:48: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:378:59: E231 missing whitespace after ',' ./build/lib/linkage/organizer/global_model.py:379:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:382:34: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:388:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:389:36: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:399:52: E231 missing whitespace after ',' -./build/lib/linkage/organizer/global_model.py:402:52: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:380:30: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:382:75: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:383:73: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:384:68: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:386:71: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:388:46: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:400:19: E231 missing whitespace after ',' ./build/lib/linkage/organizer/global_model.py:403:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:410:1: W293 blank line contains whitespace -./build/lib/linkage/organizer/global_model.py:410:9: W292 no newline at end of file +./build/lib/linkage/organizer/global_model.py:406:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:418:78: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:420:59: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:423:56: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:424:53: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:427:40: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:439:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:448:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:475:71: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:479:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:483:71: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:484:67: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:494:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:501:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:508:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:512:75: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:513:15: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:516:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:520:75: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:521:15: W291 trailing whitespace +./build/lib/linkage/organizer/global_model.py:524:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:528:25: E231 missing whitespace after ':' +./build/lib/linkage/organizer/global_model.py:529:27: E231 missing whitespace after ':' +./build/lib/linkage/organizer/global_model.py:530:26: E231 missing whitespace after ':' +./build/lib/linkage/organizer/global_model.py:539:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:542:34: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:548:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:549:36: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:559:52: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:562:52: E231 missing whitespace after ',' +./build/lib/linkage/organizer/global_model.py:563:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:570:1: W293 blank line contains whitespace +./build/lib/linkage/organizer/global_model.py:570:9: W292 no newline at end of file ./src/linkage/__init__.py:2:1: F401 'linkage.experiment.Experiment' imported but unused ./src/linkage/__init__.py:3:1: F401 'linkage.organizer.GlobalModel' imported but unused ./src/linkage/__init__.py:12:52: E231 missing whitespace after ',' @@ -542,38 +616,70 @@ ./src/linkage/experiment/baseline_corrector.py:43:18: E231 missing whitespace after ',' ./src/linkage/experiment/baseline_corrector.py:43:45: E231 missing whitespace after ',' ./src/linkage/experiment/baseline_corrector.py:43:49: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:9:1: E302 expected 2 blank lines, found 1 -./src/linkage/experiment/experiment.py:18:26: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:21:38: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:23:38: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:26:38: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:26:47: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:37:1: W293 blank line contains whitespace -./src/linkage/experiment/experiment.py:48:60: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:51:5: E303 too many blank lines (2) +./src/linkage/experiment/experiment.py:10:1: E302 expected 2 blank lines, found 1 +./src/linkage/experiment/experiment.py:19:26: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:22:38: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:24:38: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:27:38: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:27:47: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:38:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:49:60: E231 missing whitespace after ',' ./src/linkage/experiment/experiment.py:51:87: W291 trailing whitespace ./src/linkage/experiment/experiment.py:53:55: E231 missing whitespace after ',' ./src/linkage/experiment/experiment.py:53:68: E231 missing whitespace after ',' ./src/linkage/experiment/experiment.py:54:27: E231 missing whitespace after ',' ./src/linkage/experiment/experiment.py:58:39: E231 missing whitespace after ',' ./src/linkage/experiment/experiment.py:58:50: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:76:1: W293 blank line contains whitespace -./src/linkage/experiment/experiment.py:90:43: W291 trailing whitespace -./src/linkage/experiment/experiment.py:98:1: W293 blank line contains whitespace -./src/linkage/experiment/experiment.py:113:35: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:118:1: W293 blank line contains whitespace -./src/linkage/experiment/experiment.py:123:51: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:126:46: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:129:1: W293 blank line contains whitespace -./src/linkage/experiment/experiment.py:140:53: E231 missing whitespace after ':' -./src/linkage/experiment/experiment.py:141:63: E231 missing whitespace after ':' -./src/linkage/experiment/experiment.py:142:56: E231 missing whitespace after ':' +./src/linkage/experiment/experiment.py:74:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:78:79: W291 trailing whitespace +./src/linkage/experiment/experiment.py:79:77: W291 trailing whitespace +./src/linkage/experiment/experiment.py:82:75: W291 trailing whitespace +./src/linkage/experiment/experiment.py:86:43: W291 trailing whitespace +./src/linkage/experiment/experiment.py:89:74: W291 trailing whitespace +./src/linkage/experiment/experiment.py:92:76: W291 trailing whitespace +./src/linkage/experiment/experiment.py:93:74: W291 trailing whitespace +./src/linkage/experiment/experiment.py:94:32: W291 trailing whitespace +./src/linkage/experiment/experiment.py:97:75: W291 trailing whitespace +./src/linkage/experiment/experiment.py:98:50: W291 trailing whitespace +./src/linkage/experiment/experiment.py:104:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:118:43: W291 trailing whitespace +./src/linkage/experiment/experiment.py:131:76: W291 trailing whitespace +./src/linkage/experiment/experiment.py:133:34: W291 trailing whitespace +./src/linkage/experiment/experiment.py:135:1: W293 blank line contains whitespace ./src/linkage/experiment/experiment.py:143:1: W293 blank line contains whitespace -./src/linkage/experiment/experiment.py:144:34: E231 missing whitespace after ',' -./src/linkage/experiment/experiment.py:144:45: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:149:1: W293 blank line contains whitespace ./src/linkage/experiment/experiment.py:155:1: W293 blank line contains whitespace -./src/linkage/experiment/experiment.py:171:1: W293 blank line contains whitespace -./src/linkage/experiment/experiment.py:174:43: W292 no newline at end of file +./src/linkage/experiment/experiment.py:156:34: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:162:49: W291 trailing whitespace +./src/linkage/experiment/experiment.py:164:42: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:172:54: W291 trailing whitespace +./src/linkage/experiment/experiment.py:173:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:178:24: W291 trailing whitespace +./src/linkage/experiment/experiment.py:182:65: W291 trailing whitespace +./src/linkage/experiment/experiment.py:187:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:188:48: E231 missing whitespace after ':' +./src/linkage/experiment/experiment.py:189:56: E231 missing whitespace after ':' +./src/linkage/experiment/experiment.py:192:5: E303 too many blank lines (2) +./src/linkage/experiment/experiment.py:198:63: W291 trailing whitespace +./src/linkage/experiment/experiment.py:199:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:204:24: W291 trailing whitespace +./src/linkage/experiment/experiment.py:208:65: W291 trailing whitespace +./src/linkage/experiment/experiment.py:210:78: W291 trailing whitespace +./src/linkage/experiment/experiment.py:211:39: W291 trailing whitespace +./src/linkage/experiment/experiment.py:219:76: W291 trailing whitespace +./src/linkage/experiment/experiment.py:225:77: W291 trailing whitespace +./src/linkage/experiment/experiment.py:231:45: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:234:40: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:244:48: E231 missing whitespace after ':' +./src/linkage/experiment/experiment.py:245:56: E231 missing whitespace after ':' +./src/linkage/experiment/experiment.py:246:56: E231 missing whitespace after ':' +./src/linkage/experiment/experiment.py:247:56: E231 missing whitespace after ':' +./src/linkage/experiment/experiment.py:248:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:249:34: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:249:45: E231 missing whitespace after ',' +./src/linkage/experiment/experiment.py:260:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:276:1: W293 blank line contains whitespace +./src/linkage/experiment/experiment.py:279:43: W292 no newline at end of file ./src/linkage/experiment/point/__init__.py:1:1: W391 blank line at end of file ./src/linkage/experiment/point/experimental_point.py:1:1: F401 'numpy as np' imported but unused ./src/linkage/experiment/point/experimental_point.py:3:1: E302 expected 2 blank lines, found 1 @@ -599,12 +705,19 @@ ./src/linkage/experiment/point/itc_point.py:80:41: E231 missing whitespace after ',' ./src/linkage/experiment/point/itc_point.py:84:17: W291 trailing whitespace ./src/linkage/experiment/point/itc_point.py:93:1: W293 blank line contains whitespace -./src/linkage/experiment/point/itc_point.py:97:20: E221 multiple spaces before operator -./src/linkage/experiment/point/itc_point.py:97:51: E231 missing whitespace after ',' +./src/linkage/experiment/point/itc_point.py:97:74: W291 trailing whitespace ./src/linkage/experiment/point/itc_point.py:98:53: E231 missing whitespace after ',' -./src/linkage/experiment/point/itc_point.py:103:32: W291 trailing whitespace -./src/linkage/experiment/point/itc_point.py:105:71: E231 missing whitespace after ',' -./src/linkage/experiment/point/itc_point.py:107:26: W292 no newline at end of file +./src/linkage/experiment/point/itc_point.py:101:20: E221 multiple spaces before operator +./src/linkage/experiment/point/itc_point.py:101:51: E231 missing whitespace after ',' +./src/linkage/experiment/point/itc_point.py:102:1: W293 blank line contains whitespace +./src/linkage/experiment/point/itc_point.py:103:72: W291 trailing whitespace +./src/linkage/experiment/point/itc_point.py:104:42: W291 trailing whitespace +./src/linkage/experiment/point/itc_point.py:107:73: W291 trailing whitespace +./src/linkage/experiment/point/itc_point.py:109:78: W291 trailing whitespace +./src/linkage/experiment/point/itc_point.py:110:71: W291 trailing whitespace +./src/linkage/experiment/point/itc_point.py:115:32: W291 trailing whitespace +./src/linkage/experiment/point/itc_point.py:117:71: E231 missing whitespace after ',' +./src/linkage/experiment/point/itc_point.py:119:26: W292 no newline at end of file ./src/linkage/experiment/point/spec_point.py:6:1: E302 expected 2 blank lines, found 1 ./src/linkage/experiment/point/spec_point.py:8:66: W291 trailing whitespace ./src/linkage/experiment/point/spec_point.py:9:67: W291 trailing whitespace @@ -620,33 +733,36 @@ ./src/linkage/experiment/point/spec_point.py:66:42: E231 missing whitespace after ',' ./src/linkage/experiment/point/spec_point.py:70:1: W391 blank line at end of file ./src/linkage/experiment/titrator.py:6:1: E302 expected 2 blank lines, found 1 -./src/linkage/experiment/titrator.py:8:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:9:42: E231 missing whitespace after ',' -./src/linkage/experiment/titrator.py:13:45: E231 missing whitespace after ',' -./src/linkage/experiment/titrator.py:20:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:25:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:36:1: E302 expected 2 blank lines, found 1 -./src/linkage/experiment/titrator.py:54:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:63:1: E302 expected 2 blank lines, found 1 -./src/linkage/experiment/titrator.py:68:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:81:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:91:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:99:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:102:1: E303 too many blank lines (3) -./src/linkage/experiment/titrator.py:109:55: W291 trailing whitespace -./src/linkage/experiment/titrator.py:110:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:117:32: W291 trailing whitespace -./src/linkage/experiment/titrator.py:122:32: W291 trailing whitespace -./src/linkage/experiment/titrator.py:127:51: W291 trailing whitespace -./src/linkage/experiment/titrator.py:129:90: W291 trailing whitespace -./src/linkage/experiment/titrator.py:130:67: W291 trailing whitespace -./src/linkage/experiment/titrator.py:131:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:141:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:143:47: E231 missing whitespace after ',' -./src/linkage/experiment/titrator.py:144:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:152:1: W293 blank line contains whitespace -./src/linkage/experiment/titrator.py:154:5: E303 too many blank lines (2) -./src/linkage/experiment/titrator.py:166:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:9:79: W291 trailing whitespace +./src/linkage/experiment/titrator.py:16:74: W291 trailing whitespace +./src/linkage/experiment/titrator.py:18:77: W291 trailing whitespace +./src/linkage/experiment/titrator.py:19:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:23:40: W291 trailing whitespace +./src/linkage/experiment/titrator.py:29:42: E231 missing whitespace after ',' +./src/linkage/experiment/titrator.py:33:45: E231 missing whitespace after ',' +./src/linkage/experiment/titrator.py:40:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:45:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:56:1: E302 expected 2 blank lines, found 1 +./src/linkage/experiment/titrator.py:74:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:83:1: E302 expected 2 blank lines, found 1 +./src/linkage/experiment/titrator.py:88:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:98:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:117:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:120:1: E303 too many blank lines (3) +./src/linkage/experiment/titrator.py:127:55: W291 trailing whitespace +./src/linkage/experiment/titrator.py:128:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:135:32: W291 trailing whitespace +./src/linkage/experiment/titrator.py:140:32: W291 trailing whitespace +./src/linkage/experiment/titrator.py:145:51: W291 trailing whitespace +./src/linkage/experiment/titrator.py:147:90: W291 trailing whitespace +./src/linkage/experiment/titrator.py:148:67: W291 trailing whitespace +./src/linkage/experiment/titrator.py:149:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:160:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:162:47: E231 missing whitespace after ',' +./src/linkage/experiment/titrator.py:163:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:171:1: W293 blank line contains whitespace +./src/linkage/experiment/titrator.py:173:5: E303 too many blank lines (2) +./src/linkage/experiment/titrator.py:185:1: W293 blank line contains whitespace ./src/linkage/models/__init__.py:2:1: F401 'linkage.models.six_state_edta.SixStateEDTA' imported but unused ./src/linkage/models/__init__.py:3:1: F401 'linkage.models.ca_edta.CaEDTA' imported but unused ./src/linkage/models/base.py:7:1: E302 expected 2 blank lines, found 1 @@ -760,8 +876,6 @@ ./src/linkage/models/ca_edta.py:39:33: E231 missing whitespace after ',' ./src/linkage/models/ca_edta.py:47:30: E231 missing whitespace after ',' ./src/linkage/models/ca_edta.py:48:1: W293 blank line contains whitespace -./src/linkage/models/ca_edta.py:52:1: W293 blank line contains whitespace -./src/linkage/models/ca_edta.py:55:13: W292 no newline at end of file ./src/linkage/models/six_state_edta.py:25:25: E231 missing whitespace after ',' ./src/linkage/models/six_state_edta.py:25:28: E231 missing whitespace after ',' ./src/linkage/models/six_state_edta.py:25:31: E231 missing whitespace after ',' @@ -809,102 +923,136 @@ ./src/linkage/models/six_state_edta.py:99:9: E741 ambiguous variable name 'I' ./src/linkage/models/six_state_edta.py:105:1: W293 blank line contains whitespace ./src/linkage/models/six_state_edta.py:107:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:110:5: E303 too many blank lines (3) -./src/linkage/models/six_state_edta.py:112:30: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:112:35: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:112:40: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:112:45: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:112:50: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:116:30: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:116:35: E231 missing whitespace after ',' -./src/linkage/models/six_state_edta.py:117:1: W293 blank line contains whitespace -./src/linkage/models/six_state_edta.py:121:1: W391 blank line at end of file +./src/linkage/models/six_state_edta.py:110:30: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:110:35: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:110:40: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:110:45: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:110:50: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:114:30: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:114:35: E231 missing whitespace after ',' +./src/linkage/models/six_state_edta.py:115:1: W293 blank line contains whitespace +./src/linkage/models/six_state_edta.py:119:1: W391 blank line at end of file ./src/linkage/organizer/__init__.py:1:1: F401 'linkage.organizer.global_model.GlobalModel' imported but unused ./src/linkage/organizer/__init__.py:1:55: W292 no newline at end of file ./src/linkage/organizer/global_model.py:10:1: E302 expected 2 blank lines, found 1 -./src/linkage/organizer/global_model.py:17:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:35:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:42:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:53:61: W291 trailing whitespace -./src/linkage/organizer/global_model.py:55:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:61:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:62:59: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:64:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:65:58: W291 trailing whitespace -./src/linkage/organizer/global_model.py:72:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:78:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:86:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:91:77: W291 trailing whitespace -./src/linkage/organizer/global_model.py:93:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:103:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:104:47: W291 trailing whitespace -./src/linkage/organizer/global_model.py:119:41: W291 trailing whitespace -./src/linkage/organizer/global_model.py:126:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:129:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:135:27: E225 missing whitespace around operator -./src/linkage/organizer/global_model.py:158:68: E221 multiple spaces before operator -./src/linkage/organizer/global_model.py:159:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:161:5: E303 too many blank lines (2) -./src/linkage/organizer/global_model.py:163:69: W291 trailing whitespace -./src/linkage/organizer/global_model.py:166:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:172:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:175:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:176:61: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:177:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:180:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:191:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:196:49: E127 continuation line over-indented for visual indent -./src/linkage/organizer/global_model.py:197:48: E127 continuation line over-indented for visual indent -./src/linkage/organizer/global_model.py:200:57: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:204:78: W291 trailing whitespace -./src/linkage/organizer/global_model.py:205:23: W291 trailing whitespace -./src/linkage/organizer/global_model.py:212:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:213:53: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:215:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:217:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:219:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:19:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:45:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:57:61: W291 trailing whitespace +./src/linkage/organizer/global_model.py:59:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:65:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:66:59: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:68:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:69:58: W291 trailing whitespace +./src/linkage/organizer/global_model.py:76:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:82:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:90:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:95:77: W291 trailing whitespace +./src/linkage/organizer/global_model.py:97:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:107:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:108:47: W291 trailing whitespace +./src/linkage/organizer/global_model.py:123:41: W291 trailing whitespace +./src/linkage/organizer/global_model.py:130:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:133:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:135:77: W291 trailing whitespace +./src/linkage/organizer/global_model.py:136:78: W291 trailing whitespace +./src/linkage/organizer/global_model.py:138:72: W291 trailing whitespace +./src/linkage/organizer/global_model.py:141:77: W291 trailing whitespace +./src/linkage/organizer/global_model.py:142:74: W291 trailing whitespace +./src/linkage/organizer/global_model.py:143:78: W291 trailing whitespace +./src/linkage/organizer/global_model.py:146:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:162:79: W291 trailing whitespace +./src/linkage/organizer/global_model.py:163:47: W291 trailing whitespace +./src/linkage/organizer/global_model.py:178:68: E221 multiple spaces before operator +./src/linkage/organizer/global_model.py:179:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:181:5: E303 too many blank lines (2) +./src/linkage/organizer/global_model.py:183:69: W291 trailing whitespace +./src/linkage/organizer/global_model.py:186:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:192:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:195:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:196:61: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:197:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:200:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:203:79: W291 trailing whitespace +./src/linkage/organizer/global_model.py:204:75: W291 trailing whitespace +./src/linkage/organizer/global_model.py:206:73: W291 trailing whitespace +./src/linkage/organizer/global_model.py:207:78: W291 trailing whitespace +./src/linkage/organizer/global_model.py:208:52: W291 trailing whitespace +./src/linkage/organizer/global_model.py:211:81: W291 trailing whitespace +./src/linkage/organizer/global_model.py:212:34: W291 trailing whitespace +./src/linkage/organizer/global_model.py:216:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:218:58: E231 missing whitespace after ',' ./src/linkage/organizer/global_model.py:221:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:222:75: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:223:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:226:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:225:76: W291 trailing whitespace +./src/linkage/organizer/global_model.py:226:19: W291 trailing whitespace +./src/linkage/organizer/global_model.py:229:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:231:1: W293 blank line contains whitespace ./src/linkage/organizer/global_model.py:240:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:245:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:257:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:262:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:267:48: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:271:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:272:5: E303 too many blank lines (2) -./src/linkage/organizer/global_model.py:272:19: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:245:5: E303 too many blank lines (2) +./src/linkage/organizer/global_model.py:245:24: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:245:34: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:245:43: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:250:71: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:251:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:254:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:266:48: E127 continuation line over-indented for visual indent +./src/linkage/organizer/global_model.py:268:1: W293 blank line contains whitespace ./src/linkage/organizer/global_model.py:273:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:276:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:288:78: W291 trailing whitespace -./src/linkage/organizer/global_model.py:290:59: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:293:56: W291 trailing whitespace -./src/linkage/organizer/global_model.py:294:53: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:297:40: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:304:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:313:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:334:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:341:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:348:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:352:75: W291 trailing whitespace -./src/linkage/organizer/global_model.py:353:15: W291 trailing whitespace -./src/linkage/organizer/global_model.py:356:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:360:75: W291 trailing whitespace -./src/linkage/organizer/global_model.py:361:15: W291 trailing whitespace -./src/linkage/organizer/global_model.py:364:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:368:25: E231 missing whitespace after ':' -./src/linkage/organizer/global_model.py:369:27: E231 missing whitespace after ':' -./src/linkage/organizer/global_model.py:370:26: E231 missing whitespace after ':' +./src/linkage/organizer/global_model.py:307:5: E303 too many blank lines (2) +./src/linkage/organizer/global_model.py:328:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:332:14: W291 trailing whitespace +./src/linkage/organizer/global_model.py:335:49: E127 continuation line over-indented for visual indent +./src/linkage/organizer/global_model.py:336:48: E127 continuation line over-indented for visual indent +./src/linkage/organizer/global_model.py:339:57: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:343:78: W291 trailing whitespace +./src/linkage/organizer/global_model.py:350:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:351:51: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:354:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:365:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:372:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:377:48: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:378:59: E231 missing whitespace after ',' ./src/linkage/organizer/global_model.py:379:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:382:34: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:388:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:389:36: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:399:52: E231 missing whitespace after ',' -./src/linkage/organizer/global_model.py:402:52: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:380:30: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:382:75: W291 trailing whitespace +./src/linkage/organizer/global_model.py:383:73: W291 trailing whitespace +./src/linkage/organizer/global_model.py:384:68: W291 trailing whitespace +./src/linkage/organizer/global_model.py:386:71: W291 trailing whitespace +./src/linkage/organizer/global_model.py:388:46: W291 trailing whitespace +./src/linkage/organizer/global_model.py:400:19: E231 missing whitespace after ',' ./src/linkage/organizer/global_model.py:403:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:410:1: W293 blank line contains whitespace -./src/linkage/organizer/global_model.py:410:9: W292 no newline at end of file +./src/linkage/organizer/global_model.py:406:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:418:78: W291 trailing whitespace +./src/linkage/organizer/global_model.py:420:59: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:423:56: W291 trailing whitespace +./src/linkage/organizer/global_model.py:424:53: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:427:40: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:439:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:448:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:475:71: W291 trailing whitespace +./src/linkage/organizer/global_model.py:479:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:483:71: W291 trailing whitespace +./src/linkage/organizer/global_model.py:484:67: W291 trailing whitespace +./src/linkage/organizer/global_model.py:494:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:501:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:508:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:512:75: W291 trailing whitespace +./src/linkage/organizer/global_model.py:513:15: W291 trailing whitespace +./src/linkage/organizer/global_model.py:516:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:520:75: W291 trailing whitespace +./src/linkage/organizer/global_model.py:521:15: W291 trailing whitespace +./src/linkage/organizer/global_model.py:524:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:528:25: E231 missing whitespace after ':' +./src/linkage/organizer/global_model.py:529:27: E231 missing whitespace after ':' +./src/linkage/organizer/global_model.py:530:26: E231 missing whitespace after ':' +./src/linkage/organizer/global_model.py:539:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:542:34: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:548:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:549:36: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:559:52: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:562:52: E231 missing whitespace after ',' +./src/linkage/organizer/global_model.py:563:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:570:1: W293 blank line contains whitespace +./src/linkage/organizer/global_model.py:570:9: W292 no newline at end of file ./tests/conftest.py:11:1: E302 expected 2 blank lines, found 1 ./tests/conftest.py:42:63: E231 missing whitespace after ',' ./tests/conftest.py:56:49: E231 missing whitespace after ',' @@ -914,44 +1062,100 @@ ./tests/conftest.py:72:65: F541 f-string is missing placeholders ./tests/conftest.py:79:58: E231 missing whitespace after ',' ./tests/conftest.py:83:58: E231 missing whitespace after ',' -./tests/conftest.py:93:1: E302 expected 2 blank lines, found 1 -./tests/conftest.py:95:41: E231 missing whitespace after ',' -./tests/conftest.py:97:1: E302 expected 2 blank lines, found 1 -./tests/conftest.py:101:42: E231 missing whitespace after ':' -./tests/conftest.py:102:29: E128 continuation line under-indented for visual indent -./tests/conftest.py:102:36: E231 missing whitespace after ':' -./tests/conftest.py:102:55: E231 missing whitespace after ',' -./tests/conftest.py:102:57: E231 missing whitespace after ',' -./tests/conftest.py:103:29: E128 continuation line under-indented for visual indent -./tests/conftest.py:103:36: E231 missing whitespace after ':' -./tests/conftest.py:103:55: E231 missing whitespace after ',' -./tests/conftest.py:103:57: E231 missing whitespace after ',' -./tests/conftest.py:104:37: E231 missing whitespace after ',' -./tests/conftest.py:106:41: E231 missing whitespace after ':' -./tests/conftest.py:107:35: E231 missing whitespace after ':' -./tests/conftest.py:107:54: E231 missing whitespace after ',' -./tests/conftest.py:107:56: E231 missing whitespace after ',' -./tests/conftest.py:110:5: E303 too many blank lines (2) -./tests/conftest.py:112:37: E128 continuation line under-indented for visual indent -./tests/conftest.py:112:56: E231 missing whitespace after ':' -./tests/conftest.py:113:53: E127 continuation line over-indented for visual indent -./tests/conftest.py:113:57: E231 missing whitespace after ':' -./tests/conftest.py:114:37: E128 continuation line under-indented for visual indent -./tests/conftest.py:114:59: E231 missing whitespace after ':' -./tests/conftest.py:115:37: E128 continuation line under-indented for visual indent -./tests/conftest.py:117:29: E231 missing whitespace after ',' -./tests/conftest.py:117:36: E231 missing whitespace after ',' -./tests/conftest.py:117:59: E231 missing whitespace after ',' -./tests/conftest.py:118:29: E231 missing whitespace after ',' -./tests/conftest.py:118:36: E231 missing whitespace after ',' -./tests/conftest.py:118:60: E231 missing whitespace after ',' -./tests/conftest.py:118:65: E231 missing whitespace after ',' -./tests/conftest.py:122:17: E128 continuation line under-indented for visual indent -./tests/conftest.py:122:36: E231 missing whitespace after ':' -./tests/conftest.py:123:39: E231 missing whitespace after ':' -./tests/conftest.py:125:28: E231 missing whitespace after ',' -./tests/conftest.py:127:19: E231 missing whitespace after ',' -./tests/conftest.py:129:21: W292 no newline at end of file +./tests/conftest.py:87:38: E231 missing whitespace after ',' +./tests/conftest.py:96:1: E302 expected 2 blank lines, found 1 +./tests/conftest.py:99:42: E231 missing whitespace after ',' +./tests/conftest.py:100:1: W293 blank line contains whitespace +./tests/conftest.py:103:54: E231 missing whitespace after ':' +./tests/conftest.py:107:1: W293 blank line contains whitespace +./tests/conftest.py:109:50: E231 missing whitespace after ':' +./tests/conftest.py:110:53: E231 missing whitespace after ':' +./tests/conftest.py:114:1: W293 blank line contains whitespace +./tests/conftest.py:115:26: E231 missing whitespace after ',' +./tests/conftest.py:115:33: E231 missing whitespace after ',' +./tests/conftest.py:115:35: E231 missing whitespace after ',' +./tests/conftest.py:117:20: E231 missing whitespace after ':' +./tests/conftest.py:118:24: E231 missing whitespace after ':' +./tests/conftest.py:118:31: E231 missing whitespace after ',' +./tests/conftest.py:119:22: E231 missing whitespace after ':' +./tests/conftest.py:121:1: E302 expected 2 blank lines, found 1 +./tests/conftest.py:125:42: E231 missing whitespace after ':' +./tests/conftest.py:126:29: E128 continuation line under-indented for visual indent +./tests/conftest.py:126:36: E231 missing whitespace after ':' +./tests/conftest.py:126:55: E231 missing whitespace after ',' +./tests/conftest.py:126:57: E231 missing whitespace after ',' +./tests/conftest.py:127:29: E128 continuation line under-indented for visual indent +./tests/conftest.py:127:36: E231 missing whitespace after ':' +./tests/conftest.py:127:55: E231 missing whitespace after ',' +./tests/conftest.py:127:57: E231 missing whitespace after ',' +./tests/conftest.py:128:37: E231 missing whitespace after ',' +./tests/conftest.py:130:41: E231 missing whitespace after ':' +./tests/conftest.py:131:35: E231 missing whitespace after ':' +./tests/conftest.py:131:54: E231 missing whitespace after ',' +./tests/conftest.py:131:56: E231 missing whitespace after ',' +./tests/conftest.py:134:5: E303 too many blank lines (2) +./tests/conftest.py:136:37: E128 continuation line under-indented for visual indent +./tests/conftest.py:136:56: E231 missing whitespace after ':' +./tests/conftest.py:137:53: E127 continuation line over-indented for visual indent +./tests/conftest.py:137:57: E231 missing whitespace after ':' +./tests/conftest.py:138:37: E128 continuation line under-indented for visual indent +./tests/conftest.py:138:59: E231 missing whitespace after ':' +./tests/conftest.py:139:37: E128 continuation line under-indented for visual indent +./tests/conftest.py:140:37: E128 continuation line under-indented for visual indent +./tests/conftest.py:148:60: E231 missing whitespace after ',' +./tests/conftest.py:153:17: E128 continuation line under-indented for visual indent +./tests/conftest.py:153:36: E231 missing whitespace after ':' +./tests/conftest.py:154:39: E231 missing whitespace after ':' +./tests/conftest.py:160:19: E231 missing whitespace after ',' +./tests/conftest.py:162:21: W292 no newline at end of file +./tests/data/simulated_itc/generate_itc_data.py:8:1: E302 expected 2 blank lines, found 1 +./tests/data/simulated_itc/generate_itc_data.py:11:1: W293 blank line contains whitespace +./tests/data/simulated_itc/generate_itc_data.py:14:1: W293 blank line contains whitespace +./tests/data/simulated_itc/generate_itc_data.py:16:21: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:19:14: W291 trailing whitespace +./tests/data/simulated_itc/generate_itc_data.py:20:41: E231 missing whitespace after ':' +./tests/data/simulated_itc/generate_itc_data.py:21:36: E231 missing whitespace after ':' +./tests/data/simulated_itc/generate_itc_data.py:21:55: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:21:57: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:22:1: W293 blank line contains whitespace +./tests/data/simulated_itc/generate_itc_data.py:23:74: W291 trailing whitespace +./tests/data/simulated_itc/generate_itc_data.py:27:61: E231 missing whitespace after ':' +./tests/data/simulated_itc/generate_itc_data.py:32:1: W293 blank line contains whitespace +./tests/data/simulated_itc/generate_itc_data.py:33:1: W293 blank line contains whitespace +./tests/data/simulated_itc/generate_itc_data.py:34:5: E303 too many blank lines (2) +./tests/data/simulated_itc/generate_itc_data.py:35:15: W291 trailing whitespace +./tests/data/simulated_itc/generate_itc_data.py:37:58: E231 missing whitespace after ':' +./tests/data/simulated_itc/generate_itc_data.py:38:61: E231 missing whitespace after ':' +./tests/data/simulated_itc/generate_itc_data.py:43:1: W293 blank line contains whitespace +./tests/data/simulated_itc/generate_itc_data.py:44:74: W291 trailing whitespace +./tests/data/simulated_itc/generate_itc_data.py:45:19: W291 trailing whitespace +./tests/data/simulated_itc/generate_itc_data.py:47:42: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:48:1: W293 blank line contains whitespace +./tests/data/simulated_itc/generate_itc_data.py:50:26: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:50:33: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:50:35: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:51:1: W293 blank line contains whitespace +./tests/data/simulated_itc/generate_itc_data.py:52:63: W291 trailing whitespace +./tests/data/simulated_itc/generate_itc_data.py:56:44: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:56:48: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:58:1: W293 blank line contains whitespace +./tests/data/simulated_itc/generate_itc_data.py:60:29: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:60:40: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:63:47: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:64:30: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:64:47: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:64:51: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:70:1: W293 blank line contains whitespace +./tests/data/simulated_itc/generate_itc_data.py:73:59: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:74:1: W293 blank line contains whitespace +./tests/data/simulated_itc/generate_itc_data.py:76:60: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:77:1: W293 blank line contains whitespace +./tests/data/simulated_itc/generate_itc_data.py:79:39: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:84:1: W293 blank line contains whitespace +./tests/data/simulated_itc/generate_itc_data.py:86:1: W293 blank line contains whitespace +./tests/data/simulated_itc/generate_itc_data.py:87:48: E231 missing whitespace after ',' +./tests/data/simulated_itc/generate_itc_data.py:89:1: E305 expected 2 blank lines after class or function definition, found 1 +./tests/data/simulated_itc/generate_itc_data.py:89:23: W292 no newline at end of file ./tests/linkage/experiment/point/test_experimental_point.py:6:1: E302 expected 2 blank lines, found 1 ./tests/linkage/experiment/point/test_experimental_point.py:21:1: W293 blank line contains whitespace ./tests/linkage/experiment/point/test_experimental_point.py:29:1: W293 blank line contains whitespace @@ -1141,7 +1345,6 @@ ./tests/linkage/experiment/test_experiment.py:147:21: E128 continuation line under-indented for visual indent ./tests/linkage/experiment/test_experiment.py:148:21: E128 continuation line under-indented for visual indent ./tests/linkage/experiment/test_experiment.py:149:21: E128 continuation line under-indented for visual indent -./tests/linkage/experiment/test_experiment.py:150:1: W293 blank line contains whitespace ./tests/linkage/experiment/test_experiment.py:151:1: E302 expected 2 blank lines, found 1 ./tests/linkage/experiment/test_experiment.py:153:42: E231 missing whitespace after ':' ./tests/linkage/experiment/test_experiment.py:153:45: E231 missing whitespace after ',' @@ -1149,49 +1352,120 @@ ./tests/linkage/experiment/test_experiment.py:154:36: E231 missing whitespace after ':' ./tests/linkage/experiment/test_experiment.py:154:39: E231 missing whitespace after ',' ./tests/linkage/experiment/test_experiment.py:154:41: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:155:25: E231 missing whitespace after ':' -./tests/linkage/experiment/test_experiment.py:156:28: E231 missing whitespace after ':' -./tests/linkage/experiment/test_experiment.py:167:1: W293 blank line contains whitespace -./tests/linkage/experiment/test_experiment.py:173:70: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:175:1: W293 blank line contains whitespace -./tests/linkage/experiment/test_experiment.py:189:1: W293 blank line contains whitespace -./tests/linkage/experiment/test_experiment.py:203:1: W293 blank line contains whitespace -./tests/linkage/experiment/test_experiment.py:217:1: W293 blank line contains whitespace -./tests/linkage/experiment/test_experiment.py:231:1: W293 blank line contains whitespace -./tests/linkage/experiment/test_experiment.py:233:5: E303 too many blank lines (2) -./tests/linkage/experiment/test_experiment.py:240:1: W293 blank line contains whitespace -./tests/linkage/experiment/test_experiment.py:246:70: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:250:5: E303 too many blank lines (2) -./tests/linkage/experiment/test_experiment.py:263:1: W293 blank line contains whitespace -./tests/linkage/experiment/test_experiment.py:265:5: E303 too many blank lines (2) +./tests/linkage/experiment/test_experiment.py:155:42: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:155:47: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:155:51: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:156:25: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:157:28: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:168:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:177:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:181:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:186:52: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:186:57: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:186:61: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:192:52: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:192:57: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:192:61: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:196:17: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:197:17: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:198:17: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:199:17: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:200:17: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:201:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:202:76: W291 trailing whitespace +./tests/linkage/experiment/test_experiment.py:204:45: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:205:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:210:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:212:42: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:212:45: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:212:47: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:213:36: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:213:39: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:213:46: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:214:42: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:214:47: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:214:51: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:215:25: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:216:28: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:230:33: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:230:38: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:235:42: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:235:45: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:235:47: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:236:36: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:236:39: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:236:41: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:237:42: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:237:47: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:237:51: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:238:25: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:239:28: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:250:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:256:64: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:258:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:269:41: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:270:41: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:271:41: E128 continuation line under-indented for visual indent ./tests/linkage/experiment/test_experiment.py:272:1: W293 blank line contains whitespace -./tests/linkage/experiment/test_experiment.py:294:1: W293 blank line contains whitespace -./tests/linkage/experiment/test_experiment.py:298:42: E231 missing whitespace after ':' -./tests/linkage/experiment/test_experiment.py:298:45: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:298:47: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:299:25: E231 missing whitespace after ':' -./tests/linkage/experiment/test_experiment.py:300:28: E231 missing whitespace after ':' -./tests/linkage/experiment/test_experiment.py:311:1: W293 blank line contains whitespace -./tests/linkage/experiment/test_experiment.py:314:39: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:314:48: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:314:68: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:314:72: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:314:76: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:315:54: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:317:45: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:317:69: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:317:71: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:319:39: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:319:48: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:319:68: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:319:72: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:319:76: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:319:89: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:320:48: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:320:51: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:320:53: E231 missing whitespace after ',' -./tests/linkage/experiment/test_experiment.py:322:1: W293 blank line contains whitespace -./tests/linkage/experiment/test_experiment.py:322:5: W292 no newline at end of file +./tests/linkage/experiment/test_experiment.py:276:41: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:277:41: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:278:41: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:279:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:285:52: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:285:57: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:285:61: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:288:5: E303 too many blank lines (2) +./tests/linkage/experiment/test_experiment.py:298:41: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:299:41: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:300:41: E128 continuation line under-indented for visual indent +./tests/linkage/experiment/test_experiment.py:301:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:307:64: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:318:67: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:320:64: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:320:76: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:323:5: E303 too many blank lines (2) +./tests/linkage/experiment/test_experiment.py:339:42: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:339:45: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:339:47: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:340:36: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:340:39: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:340:41: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:341:42: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:341:47: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:341:51: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:342:25: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:343:28: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:348:77: W291 trailing whitespace +./tests/linkage/experiment/test_experiment.py:349:74: W291 trailing whitespace +./tests/linkage/experiment/test_experiment.py:356:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:359:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:363:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:367:42: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:367:45: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:367:47: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:368:25: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:369:28: E231 missing whitespace after ':' +./tests/linkage/experiment/test_experiment.py:380:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:383:39: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:383:48: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:383:68: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:383:72: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:383:76: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:384:54: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:386:45: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:386:69: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:386:71: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:388:39: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:388:48: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:388:68: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:388:72: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:388:76: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:388:89: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:389:48: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:389:51: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:389:53: E231 missing whitespace after ',' +./tests/linkage/experiment/test_experiment.py:391:1: W293 blank line contains whitespace +./tests/linkage/experiment/test_experiment.py:391:5: W292 no newline at end of file ./tests/linkage/experiment/test_titrator.py:12:1: E302 expected 2 blank lines, found 1 ./tests/linkage/experiment/test_titrator.py:13:1: W293 blank line contains whitespace ./tests/linkage/experiment/test_titrator.py:14:35: E231 missing whitespace after ':' @@ -1697,13 +1971,12 @@ ./tests/linkage/models/test_ca_edta.py:81:48: E231 missing whitespace after ',' ./tests/linkage/models/test_ca_edta.py:81:52: E231 missing whitespace after ',' ./tests/linkage/models/test_ca_edta.py:81:59: W292 no newline at end of file -./tests/linkage/organizer/test_global_model.py:14:1: E302 expected 2 blank lines, found 1 -./tests/linkage/organizer/test_global_model.py:21:1: W293 blank line contains whitespace -./tests/linkage/organizer/test_global_model.py:25:31: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:35:1: W293 blank line contains whitespace -./tests/linkage/organizer/test_global_model.py:37:35: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:39:1: W293 blank line contains whitespace -./tests/linkage/organizer/test_global_model.py:40:5: E303 too many blank lines (2) +./tests/linkage/organizer/test_global_model.py:10:1: F401 'linkage.experiment.experiment.Experiment' imported but unused +./tests/linkage/organizer/test_global_model.py:13:1: F401 'pandas as pd' imported but unused +./tests/linkage/organizer/test_global_model.py:16:1: E302 expected 2 blank lines, found 1 +./tests/linkage/organizer/test_global_model.py:25:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:36:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:38:35: E231 missing whitespace after ',' ./tests/linkage/organizer/test_global_model.py:43:51: W291 trailing whitespace ./tests/linkage/organizer/test_global_model.py:46:5: E303 too many blank lines (2) ./tests/linkage/organizer/test_global_model.py:50:1: W293 blank line contains whitespace @@ -1732,55 +2005,81 @@ ./tests/linkage/organizer/test_global_model.py:112:37: E231 missing whitespace after ',' ./tests/linkage/organizer/test_global_model.py:112:44: E231 missing whitespace after ',' ./tests/linkage/organizer/test_global_model.py:112:51: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:112:58: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:112:67: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:112:76: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:114:35: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:115:1: W293 blank line contains whitespace -./tests/linkage/organizer/test_global_model.py:117:33: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:117:35: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:117:37: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:117:39: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:117:41: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:122:38: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:122:48: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:125:27: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:128:5: E303 too many blank lines (2) -./tests/linkage/organizer/test_global_model.py:138:1: E302 expected 2 blank lines, found 1 -./tests/linkage/organizer/test_global_model.py:151:1: E302 expected 2 blank lines, found 1 -./tests/linkage/organizer/test_global_model.py:153:59: W291 trailing whitespace -./tests/linkage/organizer/test_global_model.py:155:51: W291 trailing whitespace -./tests/linkage/organizer/test_global_model.py:158:1: W293 blank line contains whitespace -./tests/linkage/organizer/test_global_model.py:173:1: W293 blank line contains whitespace -./tests/linkage/organizer/test_global_model.py:174:5: E303 too many blank lines (2) -./tests/linkage/organizer/test_global_model.py:174:39: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:175:38: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:177:46: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:177:56: E231 missing whitespace after ',' -./tests/linkage/organizer/test_global_model.py:185:5: E303 too many blank lines (2) -./tests/linkage/organizer/test_global_model.py:189:22: E128 continuation line under-indented for visual indent -./tests/linkage/organizer/test_global_model.py:189:47: W292 no newline at end of file +./tests/linkage/organizer/test_global_model.py:113:34: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:113:52: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:115:35: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:116:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:118:33: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:118:35: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:118:37: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:118:39: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:118:41: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:123:38: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:123:48: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:126:27: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:128:38: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:128:41: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:128:43: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:128:45: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:128:47: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:128:49: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:140:1: E302 expected 2 blank lines, found 1 +./tests/linkage/organizer/test_global_model.py:153:1: E302 expected 2 blank lines, found 1 +./tests/linkage/organizer/test_global_model.py:161:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:163:66: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:163:74: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:164:66: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:164:74: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:165:65: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:165:73: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:167:78: W291 trailing whitespace +./tests/linkage/organizer/test_global_model.py:170:73: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:171:63: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:171:66: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:176:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:177:44: W291 trailing whitespace +./tests/linkage/organizer/test_global_model.py:178:64: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:179:65: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:191:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:193:19: W291 trailing whitespace +./tests/linkage/organizer/test_global_model.py:201:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:202:44: W291 trailing whitespace +./tests/linkage/organizer/test_global_model.py:203:64: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:204:65: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:206:1: E302 expected 2 blank lines, found 1 +./tests/linkage/organizer/test_global_model.py:215:59: W291 trailing whitespace +./tests/linkage/organizer/test_global_model.py:217:51: W291 trailing whitespace +./tests/linkage/organizer/test_global_model.py:220:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:248:39: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:249:38: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:251:46: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:251:56: E231 missing whitespace after ',' +./tests/linkage/organizer/test_global_model.py:263:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:267:1: W293 blank line contains whitespace +./tests/linkage/organizer/test_global_model.py:272:22: E128 continuation line under-indented for visual indent +./tests/linkage/organizer/test_global_model.py:272:47: W292 no newline at end of file 2 C901 '_parse_linkage_docstring' is too complex (14) 4 E114 indentation is not a multiple of 4 (comment) 1 E116 unexpected indentation (comment) 15 E122 continuation line missing indentation or outdented -6 E127 continuation line over-indented for visual indent -18 E128 continuation line under-indented for visual indent +8 E127 continuation line over-indented for visual indent +33 E128 continuation line under-indented for visual indent 4 E221 multiple spaces before operator -4 E225 missing whitespace around operator -933 E231 missing whitespace after ',' +2 E225 missing whitespace around operator +1049 E231 missing whitespace after ',' 1 E261 at least two spaces before inline comment 1 E266 too many leading '#' for block comment -54 E302 expected 2 blank lines, found 1 -43 E303 too many blank lines (2) +56 E302 expected 2 blank lines, found 1 +39 E303 too many blank lines (2) +1 E305 expected 2 blank lines after class or function definition, found 1 6 E714 test for object identity should be 'is not' 2 E722 do not use bare 'except' 2 E741 ambiguous variable name 'I' -15 F401 'linkage.experiment.Experiment' imported but unused +17 F401 'linkage.experiment.Experiment' imported but unused 1 F541 f-string is missing placeholders 2 F841 local variable 'args' is assigned to but never used -203 W291 trailing whitespace -22 W292 no newline at end of file -410 W293 blank line contains whitespace +332 W291 trailing whitespace +21 W292 no newline at end of file +448 W293 blank line contains whitespace 13 W391 blank line at end of file -1762 +2060 diff --git a/reports/junit/junit.xml b/reports/junit/junit.xml index ff7c83b..ed9889a 100644 --- a/reports/junit/junit.xml +++ b/reports/junit/junit.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/run_all_tests.sh b/run_all_tests.sh index 64f19d6..a7f85d9 100644 --- a/run_all_tests.sh +++ b/run_all_tests.sh @@ -1,5 +1,12 @@ #!/bin/bash +INSTALL_DIR="$HOME/miniconda3/lib/python3.12/site-packages/linkage" + +if [ ! -d "${INSTALL_DIR}" ]; then + echo "${INSTALL_DIR} does not exist. Please check path." + exit +fi + echo "Running flake8" flake_test=`flake8 src/ --count --select=E9,F63,F7,F82 --show-source --statistics` if [[ "${flake_test}" != 0 ]]; then @@ -18,7 +25,7 @@ flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statist echo "Running coverage.py" coverage erase -coverage run --branch -m pytest --junit-xml=reports/junit/junit.xml +coverage run --source ${INSTALL_DIR} --branch -m pytest --junit-xml=reports/junit/junit.xml echo "Generating reports" coverage html diff --git a/src/linkage/__version__.py b/src/linkage/__version__.py index 8b29c93..7341562 100644 --- a/src/linkage/__version__.py +++ b/src/linkage/__version__.py @@ -1,3 +1,3 @@ -VERSION = (0, 0, 1) +VERSION = (0, 1, 0) __version__ = '.'.join(map(str, VERSION))