pythonQEPest 2.0.0a2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. pythonqepest-2.0.0a2/PKG-INFO +217 -0
  2. pythonqepest-2.0.0a2/README.md +197 -0
  3. pythonqepest-2.0.0a2/pyproject.toml +46 -0
  4. pythonqepest-2.0.0a2/pythonQEPest/.env.example +4 -0
  5. pythonqepest-2.0.0a2/pythonQEPest/__init__.py +11 -0
  6. pythonqepest-2.0.0a2/pythonQEPest/cli/__init__.py +7 -0
  7. pythonqepest-2.0.0a2/pythonQEPest/cli/cli.py +101 -0
  8. pythonqepest-2.0.0a2/pythonQEPest/config/__init__.py +11 -0
  9. pythonqepest-2.0.0a2/pythonQEPest/config/config_provider.py +9 -0
  10. pythonqepest-2.0.0a2/pythonQEPest/config/normalise.py +12 -0
  11. pythonqepest-2.0.0a2/pythonQEPest/config/qepest_config.py +31 -0
  12. pythonqepest-2.0.0a2/pythonQEPest/config/qepest_default.py +26 -0
  13. pythonqepest-2.0.0a2/pythonQEPest/core/__init__.py +7 -0
  14. pythonqepest-2.0.0a2/pythonQEPest/core/qepest.py +98 -0
  15. pythonqepest-2.0.0a2/pythonQEPest/core/qepest_meta.py +28 -0
  16. pythonqepest-2.0.0a2/pythonQEPest/data.txt +2 -0
  17. pythonqepest-2.0.0a2/pythonQEPest/data.txt.out +2 -0
  18. pythonqepest-2.0.0a2/pythonQEPest/dto/QEPestData.py +21 -0
  19. pythonqepest-2.0.0a2/pythonQEPest/dto/QEPestFile.py +34 -0
  20. pythonqepest-2.0.0a2/pythonQEPest/dto/QEPestInput.py +60 -0
  21. pythonqepest-2.0.0a2/pythonQEPest/dto/QEPestOutput.py +13 -0
  22. pythonqepest-2.0.0a2/pythonQEPest/dto/__init__.py +27 -0
  23. pythonqepest-2.0.0a2/pythonQEPest/dto/coefficients/QEPestCoefficient.py +57 -0
  24. pythonqepest-2.0.0a2/pythonQEPest/dto/coefficients/QEPestCoefficientList.py +29 -0
  25. pythonqepest-2.0.0a2/pythonQEPest/dto/coefficients/QEPestCoefficientNumerics.py +44 -0
  26. pythonqepest-2.0.0a2/pythonQEPest/dto/coefficients/__init__.py +7 -0
  27. pythonqepest-2.0.0a2/pythonQEPest/dto/normalisation/Normaliser.py +16 -0
  28. pythonqepest-2.0.0a2/pythonQEPest/dto/normalisation/__init__.py +3 -0
  29. pythonqepest-2.0.0a2/pythonQEPest/dto/pest_type/PestTypeCoefficient.py +30 -0
  30. pythonqepest-2.0.0a2/pythonQEPest/dto/pest_type/PestTypeConfig.py +9 -0
  31. pythonqepest-2.0.0a2/pythonQEPest/dto/pest_type/__init__.py +4 -0
  32. pythonqepest-2.0.0a2/pythonQEPest/gui/__init__.py +7 -0
  33. pythonqepest-2.0.0a2/pythonQEPest/gui/actions/__init__.py +9 -0
  34. pythonqepest-2.0.0a2/pythonQEPest/gui/actions/action_clicks.py +42 -0
  35. pythonqepest-2.0.0a2/pythonQEPest/gui/actions/actions_crud.py +131 -0
  36. pythonqepest-2.0.0a2/pythonQEPest/gui/actions/actions_other.py +126 -0
  37. pythonqepest-2.0.0a2/pythonQEPest/gui/elements/ButtonsFrame.py +50 -0
  38. pythonqepest-2.0.0a2/pythonQEPest/gui/elements/DataTree.py +23 -0
  39. pythonqepest-2.0.0a2/pythonQEPest/gui/elements/EditWindow.py +63 -0
  40. pythonqepest-2.0.0a2/pythonQEPest/gui/elements/Menu.py +12 -0
  41. pythonqepest-2.0.0a2/pythonQEPest/gui/elements/ResultTree.py +22 -0
  42. pythonqepest-2.0.0a2/pythonQEPest/gui/elements/SaveButton.py +10 -0
  43. pythonqepest-2.0.0a2/pythonQEPest/gui/elements/__init__.py +17 -0
  44. pythonqepest-2.0.0a2/pythonQEPest/gui/gui.py +87 -0
  45. pythonqepest-2.0.0a2/pythonQEPest/gui/gui_meta.py +17 -0
  46. pythonqepest-2.0.0a2/pythonQEPest/gui/utility/DataManager.py +76 -0
  47. pythonqepest-2.0.0a2/pythonQEPest/gui/utility/DataManagerMeta.py +8 -0
  48. pythonqepest-2.0.0a2/pythonQEPest/gui/utility/__init__.py +6 -0
  49. pythonqepest-2.0.0a2/pythonQEPest/helpers/__init__.py +17 -0
  50. pythonqepest-2.0.0a2/pythonQEPest/helpers/check_nan.py +8 -0
  51. pythonqepest-2.0.0a2/pythonQEPest/helpers/compute_df.py +5 -0
  52. pythonqepest-2.0.0a2/pythonQEPest/helpers/get_num_of_cols.py +2 -0
  53. pythonqepest-2.0.0a2/pythonQEPest/helpers/get_values_from_line.py +5 -0
  54. pythonqepest-2.0.0a2/pythonQEPest/helpers/norm.py +33 -0
  55. pythonqepest-2.0.0a2/pythonQEPest/helpers/round_to_4digs.py +2 -0
  56. pythonqepest-2.0.0a2/pythonQEPest/logger.py +58 -0
  57. pythonqepest-2.0.0a2/pythonQEPest/main.py +4 -0
  58. pythonqepest-2.0.0a2/pythonQEPest/providers/__init__.py +6 -0
  59. pythonqepest-2.0.0a2/pythonQEPest/providers/default_provider.py +23 -0
  60. pythonqepest-2.0.0a2/pythonQEPest/providers/json_provider.py +30 -0
  61. pythonqepest-2.0.0a2/pythonQEPest/providers/txt_provider.py +46 -0
  62. pythonqepest-2.0.0a2/pythonQEPest/services/QEPestFileService.py +125 -0
  63. pythonqepest-2.0.0a2/pythonQEPest/services/__init__.py +3 -0
@@ -0,0 +1,217 @@
1
+ Metadata-Version: 2.4
2
+ Name: pythonQEPest
3
+ Version: 2.0.0a2
4
+ Summary: Java QEPest but written in Python
5
+ Author: Lina
6
+ Author-email: knocker767@gmail.com
7
+ Requires-Python: >=3.12,<3.15
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.12
10
+ Classifier: Programming Language :: Python :: 3.13
11
+ Classifier: Programming Language :: Python :: 3.14
12
+ Provides-Extra: gui
13
+ Provides-Extra: rdkit
14
+ Requires-Dist: pydantic (==2.12.5)
15
+ Requires-Dist: pyperclip (>=1.11.0,<2.0.0) ; extra == "gui"
16
+ Requires-Dist: python-dotenv (>=1.2.1,<2.0.0)
17
+ Requires-Dist: rdkit (>=2024.3.1,<2026.0.0) ; extra == "rdkit"
18
+ Description-Content-Type: text/markdown
19
+
20
+ # pythonQEPest
21
+
22
+ [![pythonQEPest](https://github.com/PonyLianna/pythonQEPest/actions/workflows/python-package.yml/badge.svg)](https://github.com/PonyLianna/pythonQEPest/actions/workflows/python-package.yml)
23
+
24
+
25
+ Python implementation of QEPest (Quantitative Estimation of Pesticide), a program for scoring molecules as herbicides (QEH), insecticides (QEI), and fungicides (QEF).
26
+
27
+ Originally published in: [J Cheminform - QEPest](https://jcheminf.biomedcentral.com/articles/10.1186/s13321-014-0042-6)
28
+ Original Program Link is [here](https://static-content.springer.com/esm/art%3A10.1186%2Fs13321-014-0042-6/MediaObjects/13321_2014_42_MOESM2_ESM.zip)
29
+
30
+ ## Features
31
+
32
+ - Calculate pesticide scores for herbicidal, insecticidal, and fungicidal activity
33
+ - Command-line interface (CLI)
34
+ - Graphical User Interface (GUI)
35
+ - Support for JSON and TXT output formats
36
+
37
+ ### Pre-built binaries
38
+
39
+ Download ready-to-use executables from [Releases](https://github.com/PonyLianna/pythonQEPest/releases):
40
+
41
+ | Platform | Download |
42
+ |----------|----------|
43
+ | Windows CLI | [main.exe](https://github.com/PonyLianna/pythonQEPest/releases/download/v2.0.0-alpha/main.exe) |
44
+ | Windows GUI | [gui.exe](https://github.com/PonyLianna/pythonQEPest/releases/download/v2.0.0-alpha/gui.exe) |
45
+
46
+
47
+ ## Installation
48
+
49
+ ```bash
50
+ pip install pythonQEPest
51
+ ```
52
+
53
+ Or from source:
54
+
55
+ ```bash
56
+ git clone https://github.com/PonyLianna/pythonQEPest.git
57
+ cd pythonQEPest
58
+ poetry install
59
+ ```
60
+
61
+ ### With GUI support
62
+
63
+ ```bash
64
+ pip install pythonQEPest[gui]
65
+ # or
66
+ poetry install --extras ui
67
+ ```
68
+
69
+
70
+ ## Quick Start
71
+
72
+ ### CLI
73
+
74
+ ```bash
75
+ pythonqepest -i data.txt -o result.txt
76
+ pythonqepest --input data.txt --format json
77
+ pythonqepest -v # show version
78
+ ```
79
+
80
+ ### GUI
81
+
82
+ ```bash
83
+ pythonqepest-gui
84
+ # or
85
+ python -m pythonQEPest.gui.gui
86
+ ```
87
+
88
+ ### Python API
89
+
90
+ ```python
91
+ from pythonQEPest import QEPest, QEPestInput
92
+
93
+ # Create input data
94
+ qepest = QEPest()
95
+ qepest.initialize_coefficients()
96
+ qepest.initialize_normalisers()
97
+
98
+ # From individual values
99
+ inp = QEPestInput(
100
+ name="mol1",
101
+ mol_weight=240.2127,
102
+ log_p=3.2392,
103
+ hbond_acceptors=5,
104
+ hbond_donors=1,
105
+ rotatable_bonds=4,
106
+ aromatic_rings=1
107
+ )
108
+
109
+ result = qepest.compute_params(inp)
110
+
111
+ print(result.name) # mol1
112
+ print(result.data.qe_herb) # 0.8511
113
+ print(result.data.qe_insect) # 0.5339
114
+ print(result.data.qe_fung) # 0.6224
115
+
116
+ # Convert to array
117
+ print(result.to_array()) # ["mol1", 0.6224, 0.8511, 0.5339]
118
+ ```
119
+
120
+ ## Input Format
121
+
122
+ The input file should be a tab-separated text file with the following columns:
123
+
124
+ | Column | Description |
125
+ |--------|-------------|
126
+ | Name | Molecule name |
127
+ | MW | Molecular weight (g/mol) |
128
+ | LogP | Hydrophobicity (octanol-water partition coefficient) |
129
+ | HBA | Number of hydrogen bond acceptors |
130
+ | HBD | Number of hydrogen bond donors |
131
+ | RB | Number of rotatable bonds |
132
+ | arR | Number of aromatic rings |
133
+
134
+ Example `data.txt`:
135
+
136
+ ```
137
+ Name MW LogP HBA HBD RB arR
138
+ mol1 240.2127 3.2392 5 1 4 1
139
+ mol2 249.091 3.0273 3 1 5 1
140
+ mol3 308.354 2.1086 1 0 7 1
141
+ ```
142
+
143
+ ## Output Format
144
+
145
+ ### TXT (default output for CLI)
146
+
147
+ ```
148
+ Name QEF QEH QEI
149
+ mol1 0.6224 0.8511 0.5339
150
+ mol2 0.7310 0.9750 0.6913
151
+ ```
152
+
153
+ ### JSON
154
+
155
+ ```json
156
+ [
157
+ {"name": "mol1", "qe_fung": 0.6224, "qe_herb": 0.8511, "qe_insect": 0.5339},
158
+ {"name": "mol2", "qe_fung": 0.731, "qe_herb": 0.975, "qe_insect": 0.6913}
159
+ ]
160
+ ```
161
+
162
+ ## Configuration
163
+
164
+ ### Custom Coefficients
165
+
166
+ ```python
167
+ from pythonQEPest import QEPest
168
+
169
+ custom_coefficients = {
170
+ "herb": [
171
+ (70.77, 283.0, 84.97, -1.185),
172
+ (93.81, 3.077, 1.434, 0.6164),
173
+ # ... 6 tuples total
174
+ ],
175
+ "insect": [...],
176
+ "fung": [...]
177
+ }
178
+
179
+ qepest = QEPest(coefficients=custom_coefficients)
180
+ ```
181
+
182
+ ### Custom Normalisers
183
+
184
+ ```python
185
+ from pythonQEPest import QEPest
186
+ from pythonQEPest.dto.normalisation.Normaliser import Normaliser
187
+
188
+ qepest = QEPest(normalisers={"herb": Normaliser(...), ...})
189
+ ```
190
+
191
+ ## CLI Options
192
+
193
+ | Option | Description | Default |
194
+ |--------|-------------|---------|
195
+ | `-i`, `--input` | Input file path | data.txt |
196
+ | `-o`, `--output` | Output file path | data.out.txt |
197
+ | `-f`, `--format` | Output format (json, txt) | txt |
198
+ | `-v`, `--version` | Show version | - |
199
+
200
+ ## Development
201
+
202
+ ### Run tests
203
+
204
+ ```bash
205
+ poetry run pytest
206
+ ```
207
+
208
+ ### Build
209
+
210
+ ```bash
211
+ # CLI executable
212
+ poetry run poe build-simple
213
+
214
+ # GUI executable
215
+ poetry run poe build-gui
216
+ ```
217
+
@@ -0,0 +1,197 @@
1
+ # pythonQEPest
2
+
3
+ [![pythonQEPest](https://github.com/PonyLianna/pythonQEPest/actions/workflows/python-package.yml/badge.svg)](https://github.com/PonyLianna/pythonQEPest/actions/workflows/python-package.yml)
4
+
5
+
6
+ Python implementation of QEPest (Quantitative Estimation of Pesticide), a program for scoring molecules as herbicides (QEH), insecticides (QEI), and fungicides (QEF).
7
+
8
+ Originally published in: [J Cheminform - QEPest](https://jcheminf.biomedcentral.com/articles/10.1186/s13321-014-0042-6)
9
+ Original Program Link is [here](https://static-content.springer.com/esm/art%3A10.1186%2Fs13321-014-0042-6/MediaObjects/13321_2014_42_MOESM2_ESM.zip)
10
+
11
+ ## Features
12
+
13
+ - Calculate pesticide scores for herbicidal, insecticidal, and fungicidal activity
14
+ - Command-line interface (CLI)
15
+ - Graphical User Interface (GUI)
16
+ - Support for JSON and TXT output formats
17
+
18
+ ### Pre-built binaries
19
+
20
+ Download ready-to-use executables from [Releases](https://github.com/PonyLianna/pythonQEPest/releases):
21
+
22
+ | Platform | Download |
23
+ |----------|----------|
24
+ | Windows CLI | [main.exe](https://github.com/PonyLianna/pythonQEPest/releases/download/v2.0.0-alpha/main.exe) |
25
+ | Windows GUI | [gui.exe](https://github.com/PonyLianna/pythonQEPest/releases/download/v2.0.0-alpha/gui.exe) |
26
+
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ pip install pythonQEPest
32
+ ```
33
+
34
+ Or from source:
35
+
36
+ ```bash
37
+ git clone https://github.com/PonyLianna/pythonQEPest.git
38
+ cd pythonQEPest
39
+ poetry install
40
+ ```
41
+
42
+ ### With GUI support
43
+
44
+ ```bash
45
+ pip install pythonQEPest[gui]
46
+ # or
47
+ poetry install --extras ui
48
+ ```
49
+
50
+
51
+ ## Quick Start
52
+
53
+ ### CLI
54
+
55
+ ```bash
56
+ pythonqepest -i data.txt -o result.txt
57
+ pythonqepest --input data.txt --format json
58
+ pythonqepest -v # show version
59
+ ```
60
+
61
+ ### GUI
62
+
63
+ ```bash
64
+ pythonqepest-gui
65
+ # or
66
+ python -m pythonQEPest.gui.gui
67
+ ```
68
+
69
+ ### Python API
70
+
71
+ ```python
72
+ from pythonQEPest import QEPest, QEPestInput
73
+
74
+ # Create input data
75
+ qepest = QEPest()
76
+ qepest.initialize_coefficients()
77
+ qepest.initialize_normalisers()
78
+
79
+ # From individual values
80
+ inp = QEPestInput(
81
+ name="mol1",
82
+ mol_weight=240.2127,
83
+ log_p=3.2392,
84
+ hbond_acceptors=5,
85
+ hbond_donors=1,
86
+ rotatable_bonds=4,
87
+ aromatic_rings=1
88
+ )
89
+
90
+ result = qepest.compute_params(inp)
91
+
92
+ print(result.name) # mol1
93
+ print(result.data.qe_herb) # 0.8511
94
+ print(result.data.qe_insect) # 0.5339
95
+ print(result.data.qe_fung) # 0.6224
96
+
97
+ # Convert to array
98
+ print(result.to_array()) # ["mol1", 0.6224, 0.8511, 0.5339]
99
+ ```
100
+
101
+ ## Input Format
102
+
103
+ The input file should be a tab-separated text file with the following columns:
104
+
105
+ | Column | Description |
106
+ |--------|-------------|
107
+ | Name | Molecule name |
108
+ | MW | Molecular weight (g/mol) |
109
+ | LogP | Hydrophobicity (octanol-water partition coefficient) |
110
+ | HBA | Number of hydrogen bond acceptors |
111
+ | HBD | Number of hydrogen bond donors |
112
+ | RB | Number of rotatable bonds |
113
+ | arR | Number of aromatic rings |
114
+
115
+ Example `data.txt`:
116
+
117
+ ```
118
+ Name MW LogP HBA HBD RB arR
119
+ mol1 240.2127 3.2392 5 1 4 1
120
+ mol2 249.091 3.0273 3 1 5 1
121
+ mol3 308.354 2.1086 1 0 7 1
122
+ ```
123
+
124
+ ## Output Format
125
+
126
+ ### TXT (default output for CLI)
127
+
128
+ ```
129
+ Name QEF QEH QEI
130
+ mol1 0.6224 0.8511 0.5339
131
+ mol2 0.7310 0.9750 0.6913
132
+ ```
133
+
134
+ ### JSON
135
+
136
+ ```json
137
+ [
138
+ {"name": "mol1", "qe_fung": 0.6224, "qe_herb": 0.8511, "qe_insect": 0.5339},
139
+ {"name": "mol2", "qe_fung": 0.731, "qe_herb": 0.975, "qe_insect": 0.6913}
140
+ ]
141
+ ```
142
+
143
+ ## Configuration
144
+
145
+ ### Custom Coefficients
146
+
147
+ ```python
148
+ from pythonQEPest import QEPest
149
+
150
+ custom_coefficients = {
151
+ "herb": [
152
+ (70.77, 283.0, 84.97, -1.185),
153
+ (93.81, 3.077, 1.434, 0.6164),
154
+ # ... 6 tuples total
155
+ ],
156
+ "insect": [...],
157
+ "fung": [...]
158
+ }
159
+
160
+ qepest = QEPest(coefficients=custom_coefficients)
161
+ ```
162
+
163
+ ### Custom Normalisers
164
+
165
+ ```python
166
+ from pythonQEPest import QEPest
167
+ from pythonQEPest.dto.normalisation.Normaliser import Normaliser
168
+
169
+ qepest = QEPest(normalisers={"herb": Normaliser(...), ...})
170
+ ```
171
+
172
+ ## CLI Options
173
+
174
+ | Option | Description | Default |
175
+ |--------|-------------|---------|
176
+ | `-i`, `--input` | Input file path | data.txt |
177
+ | `-o`, `--output` | Output file path | data.out.txt |
178
+ | `-f`, `--format` | Output format (json, txt) | txt |
179
+ | `-v`, `--version` | Show version | - |
180
+
181
+ ## Development
182
+
183
+ ### Run tests
184
+
185
+ ```bash
186
+ poetry run pytest
187
+ ```
188
+
189
+ ### Build
190
+
191
+ ```bash
192
+ # CLI executable
193
+ poetry run poe build-simple
194
+
195
+ # GUI executable
196
+ poetry run poe build-gui
197
+ ```
@@ -0,0 +1,46 @@
1
+ [project]
2
+ name = "pythonQEPest"
3
+ version = "2.0.0a2"
4
+ description = "Java QEPest but written in Python"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12,<3.15"
7
+ authors = [{ name = "Lina", email = "knocker767@gmail.com" }]
8
+ dependencies = ["pydantic==2.12.5", "python-dotenv>=1.2.1,<2.0.0"]
9
+
10
+ [project.optional-dependencies]
11
+ gui = ["pyperclip>=1.11.0,<2.0.0"]
12
+ rdkit = ["rdkit (>=2024.3.1,<2026.0.0)"]
13
+
14
+ [project.scripts]
15
+ pythonqepest = "pythonQEPest.cli.cli:main"
16
+
17
+ [project.gui-scripts]
18
+ pythonqepest-gui = "pythonQEPest.gui.gui:main"
19
+
20
+ [tool.poetry]
21
+ packages = [{ include = "pythonQEPest" }]
22
+
23
+ [dependency-groups]
24
+ dev = [
25
+ "pytest (>=9.0.0)",
26
+ "pre-commit (>=4.3.0,<5.0.0)",
27
+ "pyinstaller (>=6.18.0,<7.0.0)",
28
+ "poethepoet[poetry_plugin] (>=0.39.0)",
29
+ "pytest-cov (>=7.0.0,<8.0.0)",
30
+ "twine (>=6.2.0,<7.0.0)",
31
+ ]
32
+
33
+ [build-system]
34
+ requires = ["poetry-core>=1.0.0", "setuptools>=40.8.0"]
35
+ build-backend = "poetry.core.masonry.api"
36
+
37
+ [tool.flake8]
38
+ max-line-length = 88
39
+ extend-ignore = ["E203", "W503"]
40
+ exclude = [".venv", ".git", "__pycache__", "build", "dist"]
41
+
42
+ [tool.poe.tasks]
43
+ test = "pytest"
44
+ build-simple = "pyinstaller --onefile pythonQEPest/main.py"
45
+ build-gui = "pyinstaller --onefile --noconsole pythonQEPest/gui/gui.py"
46
+ publish-pypy = "twine upload --repository pythonQEPest dist/*"
@@ -0,0 +1,4 @@
1
+ LOG_LEVEL="INFO"
2
+ LOG_FILE_LOCATION="logs/app.log"
3
+
4
+ APP_DEBUG_ENABLE="false"
@@ -0,0 +1,11 @@
1
+ from pythonQEPest.core import QEPest
2
+ from pythonQEPest.dto import QEPestData
3
+ from pythonQEPest.dto import QEPestInput
4
+ from pythonQEPest.dto import QEPestOutput
5
+
6
+ __all__ = [
7
+ "QEPest",
8
+ "QEPestData",
9
+ "QEPestInput",
10
+ "QEPestOutput",
11
+ ]
@@ -0,0 +1,7 @@
1
+ def main():
2
+ from pythonQEPest.cli.cli import main as _main
3
+
4
+ return _main()
5
+
6
+
7
+ __all__ = ["main"]
@@ -0,0 +1,101 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import logging
5
+ from importlib.metadata import PackageNotFoundError, version
6
+ from pathlib import Path
7
+ from typing import Sequence
8
+
9
+ from pythonQEPest.dto import QEPestFile
10
+ from pythonQEPest.services.QEPestFileService import QEPestFileService
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ def _resolve_package_version() -> str:
16
+ try:
17
+ return version("pythonQEPest")
18
+ except PackageNotFoundError:
19
+ pass
20
+
21
+ try:
22
+ import tomllib # py3.11+
23
+
24
+ pyproject = Path(__file__).resolve().parents[2] / "pyproject.toml"
25
+ data = tomllib.loads(pyproject.read_text(encoding="utf-8"))
26
+ return data["project"]["version"]
27
+ except Exception:
28
+ return "0+unknown"
29
+
30
+
31
+ def build_parser() -> argparse.ArgumentParser:
32
+ parser = argparse.ArgumentParser(
33
+ prog="pythonqepest",
34
+ description="Compute QEPest scores from a tab-separated input file.",
35
+ )
36
+ parser.add_argument(
37
+ "-v",
38
+ "--version",
39
+ action="version",
40
+ version=f"%(prog)s {_resolve_package_version()}",
41
+ help="Show program's version number.",
42
+ )
43
+ parser.add_argument(
44
+ "-i",
45
+ "--input",
46
+ default="data.txt",
47
+ help="Path to input tab-separated file with "
48
+ + "QEPest descriptors (default: data.txt).",
49
+ )
50
+
51
+ parser.add_argument(
52
+ "-o",
53
+ "--output",
54
+ default="data.out.txt",
55
+ help="Path to output tab-separated file with "
56
+ + "QEPest descriptors (default: data.txt.out).",
57
+ )
58
+
59
+ parser.add_argument(
60
+ "-f",
61
+ "--format",
62
+ default="txt",
63
+ help="Format to output file with QEPest (json, txt).",
64
+ )
65
+
66
+ parser.add_argument(
67
+ "--smiles",
68
+ action="store_true",
69
+ help="Input file contains SMILES strings "
70
+ "(one per line) instead of descriptors.",
71
+ )
72
+ return parser
73
+
74
+
75
+ def main(argv: Sequence[str] | None = None) -> int:
76
+ from dotenv import load_dotenv
77
+
78
+ from pythonQEPest.core.qepest import QEPest
79
+ from pythonQEPest.logger import init_logger
80
+
81
+ args = build_parser().parse_args(argv)
82
+
83
+ load_dotenv()
84
+ init_logger()
85
+
86
+ logger.debug("CLI initiated")
87
+ logger.info(f"CLI args: {argv}")
88
+
89
+ service = QEPestFileService(
90
+ qepest=QEPest(),
91
+ qepest_file=QEPestFile(
92
+ input_file=args.input,
93
+ output_file=args.output,
94
+ format=args.format,
95
+ smiles=args.smiles,
96
+ ),
97
+ )
98
+
99
+ service.read_file_and_compute_params()
100
+
101
+ return 0 if not service.error else 1
@@ -0,0 +1,11 @@
1
+ from pythonQEPest.config.qepest_default import qepest_default
2
+ from pythonQEPest.config.normalise import normalise_default
3
+ from pythonQEPest.config.qepest_config import QEPestConfig
4
+ from pythonQEPest.config.config_provider import ConfigProvider
5
+
6
+ __all__ = [
7
+ "normalise_default",
8
+ "qepest_default",
9
+ "ConfigProvider",
10
+ "QEPestConfig",
11
+ ]
@@ -0,0 +1,9 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ from pythonQEPest.config.qepest_config import QEPestConfig
4
+
5
+
6
+ class ConfigProvider(ABC):
7
+ @abstractmethod
8
+ def load(self) -> QEPestConfig:
9
+ pass
@@ -0,0 +1,12 @@
1
+ normalise_default = {
2
+ "herb": (69.5849922, 94.4228257, 120.4572352, 228.1589796, 89.7012502, 276.9634213),
3
+ "insect": (
4
+ 78.2919965,
5
+ 71.2829691,
6
+ 133.9224801,
7
+ 331.170104,
8
+ 70.5540709,
9
+ 193.0023343,
10
+ ),
11
+ "fung": (53.3719946, 52.773116, 73.7976536, 144.9887053, 41.4385926, 102.3024319),
12
+ }
@@ -0,0 +1,31 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel
4
+
5
+ from pythonQEPest.dto.pest_type.PestTypeConfig import PestTypeConfig
6
+
7
+
8
+ class QEPestConfig(BaseModel):
9
+ name: Optional[str] = "HerbInsectFung"
10
+ pest_types: list[PestTypeConfig]
11
+
12
+ def get_pest_names(self) -> list[str]:
13
+ return [pest.name for pest in self.pest_types]
14
+
15
+ def get_coefficients(
16
+ self, pest_name: str
17
+ ) -> list[tuple[float, float, float, float]]:
18
+ for pest in self.pest_types:
19
+ if pest.name == pest_name:
20
+ return pest.coefficients.as_set()
21
+
22
+ raise ValueError(f"Pest type '{pest_name}' not found")
23
+
24
+ def get_normaliser(
25
+ self, pest_name: str
26
+ ) -> tuple[float, float, float, float, float, float]:
27
+ for pest in self.pest_types:
28
+ if pest.name == pest_name:
29
+ return pest.normaliser
30
+
31
+ raise ValueError(f"Pest type '{pest_name}' not found")
@@ -0,0 +1,26 @@
1
+ qepest_default = {
2
+ "herb": [
3
+ (70.77, 283.0, 84.97, -1.185), # mwH
4
+ (93.81, 3.077, 1.434, 0.6164), # logpH
5
+ (117.6, 2.409, 1.567, 7.155), # hbaH
6
+ (233.4, 0.4535, -1.48, 4.47), # hbdH
7
+ (84.7, 4.758, -2.423, 5.437), # rbH
8
+ (301.8, 1.101, 0.8869, -22.81), # arRCH
9
+ ],
10
+ "insect": [
11
+ (76.38, 298.3, 83.64, 1.912), # mwI
12
+ (74.27, 4.555, -2.193, -2.987), # logpI
13
+ (139.4, 1.363, 1.283, 0.5341), # hbaI
14
+ (670.6, -1.163, 0.7856, 0.7951), # hbdI
15
+ (65.49, 6.219, -2.448, 5.318), # rbI
16
+ (287.5, 0.305, 1.554, -88.64), # arRCI
17
+ ],
18
+ "fung": [
19
+ (51.03, 314.2, -56.31, 2.342), # mwF
20
+ (50.73, 3.674, -1.238, 2.067), # logpF
21
+ (73.79, 1.841, 1.326, 0.5158), # hbaF
22
+ (164.7, -0.9762, -2.027, 1.384), # hbdF
23
+ (40.91, 1.822, 2.582, 0.6235), # rbF
24
+ (134.4, 0.8383, 1.347, -31.17), # arRCF
25
+ ],
26
+ }
@@ -0,0 +1,7 @@
1
+ from .qepest import QEPest
2
+ from .qepest_meta import QEPestMeta
3
+
4
+ __all__ = [
5
+ "QEPestMeta",
6
+ "QEPest",
7
+ ]