ensemble-analyzer 0.0.10a6__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.
Potentially problematic release.
This version of ensemble-analyzer might be problematic. Click here for more details.
- ensemble_analyzer-0.0.10a6/LICENSE +21 -0
- ensemble_analyzer-0.0.10a6/PKG-INFO +240 -0
- ensemble_analyzer-0.0.10a6/README.md +204 -0
- ensemble_analyzer-0.0.10a6/pyproject.toml +75 -0
- ensemble_analyzer-0.0.10a6/setup.cfg +4 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/__init__.py +0 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/__main__.py +5 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_calculators/__init__.py +12 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_calculators/_gaussian.py +91 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_calculators/_orca.py +91 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_calculators/base.py +44 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_clustering/__init__.py +0 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_clustering/cluster_config.py +27 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_clustering/cluster_manager.py +471 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_conformer/__init__.py +0 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_conformer/conformer.py +183 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_conformer/energy_data.py +108 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_conformer/spectral_data.py +79 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_logger/__init__.py +0 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_logger/create_log.py +44 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_logger/formatter.py +36 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_logger/logger.py +261 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_managers/__init__.py +0 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_managers/calculation_config.py +230 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_managers/calculation_executor.py +109 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_managers/calculator_orchestration.py +114 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_managers/checkpoint_manager.py +68 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_managers/protocol_executor.py +272 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_managers/protocol_manager.py +45 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_managers/pruning_manager.py +267 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_parsers/__init__.py +12 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_parsers/_gaussian.py +144 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_parsers/_orca.py +220 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_parsers/base.py +72 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_protocol/__init__.py +0 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_protocol/protocol.py +220 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_protocol/solvent.py +19 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_spectral/__init__.py +0 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_spectral/base.py +260 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_spectral/comp_electronic.py +23 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_spectral/comp_vibronic.py +21 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_spectral/compare.py +195 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_spectral/experimental.py +122 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/_spectral/graph_default.py +95 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/cli/__init__.py +0 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/cli/get_av_energy.py +342 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/cli/pickle_editor/__init__.py +11 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/cli/pickle_editor/cli.py +269 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/cli/pickle_editor/core.py +397 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/cli/pickle_editor/tui.py +465 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/cli/protocol_wizard.py +513 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/cli/regraph.py +83 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/clustering.py +253 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/constants.py +78 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/ensemble_io.py +92 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/graph.py +61 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/io_utils.py +61 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/launch.py +75 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/parameters_file/basis_sets +436 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/parameters_file/default_protocol.json +16 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/parameters_file/default_threshold.json +26 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/parameters_file/functionals +144 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/parser_arguments.py +287 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/parser_parameter.py +137 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/rrho.py +382 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer/title.py +29 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer.egg-info/PKG-INFO +240 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer.egg-info/SOURCES.txt +70 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer.egg-info/dependency_links.txt +1 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer.egg-info/entry_points.txt +6 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer.egg-info/requires.txt +8 -0
- ensemble_analyzer-0.0.10a6/src/ensemble_analyzer.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Andrea Pellegrini
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ensemble-analyzer
|
|
3
|
+
Version: 0.0.10a6
|
|
4
|
+
Summary: Automatic Refinement of Conformational Ensemble
|
|
5
|
+
Author-email: Andrea Pellegrini <andrea.pellegrini15@unibo.it>, Paolo Righi <paolo.righi@unibo.it>
|
|
6
|
+
Maintainer-email: Andrea Pellegrini <andrea.pellegrini15@unibo.it>, Paolo Righi <paolo.righi@unibo.it>
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/andre-cloud/ensemble_analyzer
|
|
9
|
+
Keywords: computational-chemistry,conformational-analysis,ensemble-refinement,automatization,ase,quantum-chemistry
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
22
|
+
Classifier: Operating System :: OS Independent
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: numpy==2.2.0
|
|
28
|
+
Requires-Dist: scipy==1.16.3
|
|
29
|
+
Requires-Dist: matplotlib==3.10.7
|
|
30
|
+
Requires-Dist: scikit-learn==1.7.2
|
|
31
|
+
Requires-Dist: ase==3.24.0
|
|
32
|
+
Requires-Dist: numba==0.61.2
|
|
33
|
+
Requires-Dist: tabulate==0.9.0
|
|
34
|
+
Requires-Dist: InquirerPy==0.3.4
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# Ensemble Analyzer
|
|
38
|
+
[](https://www.python.org/downloads/)
|
|
39
|
+
[](LICENSE)
|
|
40
|
+
|
|
41
|
+
## Conformer Ensemble Pruning Software
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+

|
|
45
|
+
|
|
46
|
+
**EnAn** (Ensemble Analysis) is a Python framework for automated conformational analysis and ensemble processing in computational chemistry workflows.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 🎯 Key Features
|
|
51
|
+
|
|
52
|
+
### Core Capabilities
|
|
53
|
+
- ⚡ **Multi-Protocol Workflows**: Sequential optimization/frequency calculations with automatic pruning
|
|
54
|
+
- 🔬 **Quantum Chemistry Integration**: Support for ORCA and Gaussian
|
|
55
|
+
- 📊 **Advanced Clustering**: PCA-based conformer clustering with multiple feature extraction methods
|
|
56
|
+
- 🎨 **Spectral Analysis**: Generate weighted IR, VCD, UV-vis, and ECD spectra
|
|
57
|
+
- 🔄 **Checkpoint System**: Automatic restart capability with atomic file operations
|
|
58
|
+
|
|
59
|
+
### Analysis Tools
|
|
60
|
+
- **Thermochemistry**: Grimme's qRRHO implementation for every integration
|
|
61
|
+
- **Clustering Method**: Distance matrix eigenvalues (rotation/translation invariant).
|
|
62
|
+
- **Pruning**: Intelligent energy-based filtering with Boltzmann weighting
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 📦 Installation
|
|
68
|
+
|
|
69
|
+
### Requirements
|
|
70
|
+
- **Python** ≥ 3.9
|
|
71
|
+
- **Core**: NumPy, SciPy, Matplotlib, ASE
|
|
72
|
+
- **Clustering**: scikit-learn
|
|
73
|
+
- **Acceleration**: Numba
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pip install ensemble-analyzer
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
- Install [ORCA](https://orcaforum.kofo.mpg.de/app.php/portal) from the ORCA Forum
|
|
80
|
+
- *Optional*: Install Gaussian, if licensed
|
|
81
|
+
|
|
82
|
+
- Export ORCA verion
|
|
83
|
+
```bash
|
|
84
|
+
export ORCAVERSION="x.y.z"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 🚀 Quick Start
|
|
88
|
+
|
|
89
|
+
### 1. Define your protocol file
|
|
90
|
+
Create `protocol.json`
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"0": {"funcional": "r2SCAN-3c", "opt": true, "freq": true,"cluster": 5, "comment": "Initial Optimization cluster into 5 families"},
|
|
94
|
+
"1": {"funcional": "wB97X-D4rev", "basis": "def2-QZVPPD", "comment": "Single Point energy evaluation"}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 2. Basic Usage
|
|
100
|
+
```bash
|
|
101
|
+
ensemble_analyzer --ensemble conformers.xyz --protocol protocol.json --output calculation.out --cpu 8 --temperature 298.15
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 3. Restart from Checkpoint
|
|
105
|
+
```bash
|
|
106
|
+
# Automatically resumes from last completed protocol
|
|
107
|
+
ensemble_analyzer --restart
|
|
108
|
+
```
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
### Protocol Parameters
|
|
112
|
+
|
|
113
|
+
| Parameter | Type | Description | Example |
|
|
114
|
+
|-----------|------|-------------|---------|
|
|
115
|
+
| **Calculation Settings** ||||
|
|
116
|
+
| `functional` | str | DFT functional or method | `"B3LYP"`, `"xtb"`, `"HF-3c"` |
|
|
117
|
+
| `basis` | str | Basis set (auto for composite methods) | `"def2-SVP"`, `"def2-TZVP"` |
|
|
118
|
+
| `calculator` | str | QM program | `"orca"` (default), `"gaussian"` |
|
|
119
|
+
| `opt` | bool | Optimize geometry | `true`, `false` |
|
|
120
|
+
| `freq` | bool | Calculate frequencies | `true`, `false` |
|
|
121
|
+
| `mult` | int | Spin multiplicity | `1` (singlet), `2` (doublet) |
|
|
122
|
+
| `charge` | int | Molecular charge | |
|
|
123
|
+
| `calculator` | str | Set the calculator | `orca` (default), `gaussian` |
|
|
124
|
+
| **Pruning Thresholds** ||||
|
|
125
|
+
| `thrG` | float | Energy similarity threshold [kcal/mol] | `3.0`, `5.0` |
|
|
126
|
+
| `thrB` | float | Rotatory constant threshold [cm⁻¹] | `30.0`, `50.0` |
|
|
127
|
+
| `thrGMAX` | float | Energy window cutoff [kcal/mol] | `10.0` |
|
|
128
|
+
| `cluster` | bool/int | Enable clustering | `true` (auto), `5` (fixed) |
|
|
129
|
+
| `no_prune` | bool | Disable pruning | `false` (default) |
|
|
130
|
+
| **Advanced** ||||
|
|
131
|
+
| `solvent` | dict | Implicit solvation | `{"solvent": "water", "model": "SMD"}` |
|
|
132
|
+
| `constrains` | list | Geometry constraints (only on cartesians)| `[1,2]` (fix cartesians) |
|
|
133
|
+
| `monitor_internals` | list | Track bond/angle/dihedral | `[[0,1], [0,1,2]]` |
|
|
134
|
+
| `skip_opt_fail` | bool | Skip failed optimizations | `false` (default) |
|
|
135
|
+
| `skip_retention_rate` | bool | Skip check for retention rate | `false` (default) |
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Standalone CLI applications
|
|
140
|
+
|
|
141
|
+
### Protocol Wizard
|
|
142
|
+
|
|
143
|
+
If you don't want to create from scratch the protocol file, the `enan_protocol_wizard` is an automatic and interactive way to create this essential file.
|
|
144
|
+
It is divided into three different level of configuration: i) basic, where all the essential parameters are asked, ii) intermediate, and iii) advance.
|
|
145
|
+
Feel free to browse all the possible protocol options and parameters.
|
|
146
|
+
|
|
147
|
+
### Regrapher
|
|
148
|
+
|
|
149
|
+
If you want to change the convolution of your graphs, you can edit the setting.json file. Here, all the global settings are present. When finished, the command `enan_regraph` come handy. It re-run the Graph workflow with these new setting and in few time, you'll have your new graphs.
|
|
150
|
+
```bash
|
|
151
|
+
usage: enan_regraph [-h] [-rb READ_BOLTZ] [-no-nm] [-w] [--disable-color] idx [idx ...]
|
|
152
|
+
|
|
153
|
+
positional arguments:
|
|
154
|
+
idx Protocol's number to (re-)generate the graphs
|
|
155
|
+
|
|
156
|
+
options:
|
|
157
|
+
-h, --help show this help message and exit
|
|
158
|
+
-rb READ_BOLTZ, --read-boltz READ_BOLTZ
|
|
159
|
+
Read Boltzmann population from a specific protocol
|
|
160
|
+
-no-nm, --no-nm Do not save the nm graphs
|
|
161
|
+
-w, --weight Show Weighting function
|
|
162
|
+
--disable-color Disable colored output
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Graph Editor
|
|
166
|
+
|
|
167
|
+
All graphs are saved also as a pickle. This file can be reloaded and from there you can modify every single element of the Matplotlib Figure store in it. This requires some programming skills and, especially, time. Here is where `enan_graph_editor` comes to play. It is once again an interactive terminal interface (based both on rich or InquierPy library) where you can change and personalize every pickle. If you have to modify more files at once, a *batch* mode is implemented as well, so to by-pass the limitation of the manual selection of the interactive TUI.
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
usage: enan_graph_editor [-h] [--batch] [--list] [--rename OLD NEW] [--rename-file RENAME_FILE] [--color LABEL COLOR] [--linestyle LABEL STYLE] [--linewidth LABEL WIDTH] [--alpha LABEL ALPHA] [--output OUTPUT] [--format {pickle,png,pdf,svg}] [--preview] [--no-strict]
|
|
171
|
+
[--verbose]
|
|
172
|
+
pickle_file
|
|
173
|
+
|
|
174
|
+
Interactive/batch editor for matplotlib pickles
|
|
175
|
+
|
|
176
|
+
positional arguments:
|
|
177
|
+
pickle_file Matplotlib pickle file
|
|
178
|
+
|
|
179
|
+
options:
|
|
180
|
+
-h, --help show this help message and exit
|
|
181
|
+
--batch, -b Batch mode (non-interactive)
|
|
182
|
+
--no-strict Disable strict validation
|
|
183
|
+
--verbose, -v Verbose output
|
|
184
|
+
|
|
185
|
+
batch mode options:
|
|
186
|
+
--list, -l List labels and exit
|
|
187
|
+
--rename OLD NEW, -r OLD NEW
|
|
188
|
+
Rename label
|
|
189
|
+
--rename-file RENAME_FILE, -rf RENAME_FILE
|
|
190
|
+
Mapping file OLD=NEW
|
|
191
|
+
--color LABEL COLOR, -c LABEL COLOR
|
|
192
|
+
Change colour
|
|
193
|
+
--linestyle LABEL STYLE, -ls LABEL STYLE
|
|
194
|
+
Change line linestyle (e.g., -, --, :, -. )
|
|
195
|
+
--linewidth LABEL WIDTH, -lw LABEL WIDTH
|
|
196
|
+
Change line linewidth (float)
|
|
197
|
+
--alpha LABEL ALPHA, -a LABEL ALPHA
|
|
198
|
+
Change line transparency (0-1)
|
|
199
|
+
--output OUTPUT, -o OUTPUT
|
|
200
|
+
Output file
|
|
201
|
+
--format {pickle,png,pdf,svg}, -f {pickle,png,pdf,svg}
|
|
202
|
+
Output format
|
|
203
|
+
|
|
204
|
+
DEFAULT MODE: Interactive TUI
|
|
205
|
+
python enan_graph_editor plot.pkl
|
|
206
|
+
|
|
207
|
+
BATCH MODE (examples):
|
|
208
|
+
python enan_graph_editor plot.pkl --batch --list
|
|
209
|
+
python enan_graph_editor plot.pkl --batch --rename "Protocol 1" "Proto A"
|
|
210
|
+
python enan_graph_editor plot.pkl --batch --color "Experimental" red --output new.pkl
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
## 🤝 Contributing
|
|
215
|
+
|
|
216
|
+
### Development Workflow
|
|
217
|
+
```bash
|
|
218
|
+
# Fork and clone
|
|
219
|
+
git clone https://github.com/andre-cloud/ensemble_analyzer.git
|
|
220
|
+
cd ensemble_analyzer
|
|
221
|
+
|
|
222
|
+
# Create feature branch
|
|
223
|
+
git checkout -b feature/awesome-feature
|
|
224
|
+
|
|
225
|
+
# Install dev dependencies
|
|
226
|
+
pip install -e .
|
|
227
|
+
|
|
228
|
+
# Commit and push
|
|
229
|
+
git commit -m "Add awesome feature"
|
|
230
|
+
git push origin feature/awesome-feature
|
|
231
|
+
```
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## 📄 License
|
|
235
|
+
|
|
236
|
+
This software is licensed under the MIT-3.0 License. See the LICENSE file for details.
|
|
237
|
+
|
|
238
|
+
## 📞 Support and contact
|
|
239
|
+
|
|
240
|
+
For any questions or support, please contact [by email](mailto:andrea.pellegrini15@unibo.it,paolo.righi@unibo.it).
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Ensemble Analyzer
|
|
2
|
+
[](https://www.python.org/downloads/)
|
|
3
|
+
[](LICENSE)
|
|
4
|
+
|
|
5
|
+
## Conformer Ensemble Pruning Software
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
**EnAn** (Ensemble Analysis) is a Python framework for automated conformational analysis and ensemble processing in computational chemistry workflows.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 🎯 Key Features
|
|
15
|
+
|
|
16
|
+
### Core Capabilities
|
|
17
|
+
- ⚡ **Multi-Protocol Workflows**: Sequential optimization/frequency calculations with automatic pruning
|
|
18
|
+
- 🔬 **Quantum Chemistry Integration**: Support for ORCA and Gaussian
|
|
19
|
+
- 📊 **Advanced Clustering**: PCA-based conformer clustering with multiple feature extraction methods
|
|
20
|
+
- 🎨 **Spectral Analysis**: Generate weighted IR, VCD, UV-vis, and ECD spectra
|
|
21
|
+
- 🔄 **Checkpoint System**: Automatic restart capability with atomic file operations
|
|
22
|
+
|
|
23
|
+
### Analysis Tools
|
|
24
|
+
- **Thermochemistry**: Grimme's qRRHO implementation for every integration
|
|
25
|
+
- **Clustering Method**: Distance matrix eigenvalues (rotation/translation invariant).
|
|
26
|
+
- **Pruning**: Intelligent energy-based filtering with Boltzmann weighting
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 📦 Installation
|
|
32
|
+
|
|
33
|
+
### Requirements
|
|
34
|
+
- **Python** ≥ 3.9
|
|
35
|
+
- **Core**: NumPy, SciPy, Matplotlib, ASE
|
|
36
|
+
- **Clustering**: scikit-learn
|
|
37
|
+
- **Acceleration**: Numba
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install ensemble-analyzer
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
- Install [ORCA](https://orcaforum.kofo.mpg.de/app.php/portal) from the ORCA Forum
|
|
44
|
+
- *Optional*: Install Gaussian, if licensed
|
|
45
|
+
|
|
46
|
+
- Export ORCA verion
|
|
47
|
+
```bash
|
|
48
|
+
export ORCAVERSION="x.y.z"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 🚀 Quick Start
|
|
52
|
+
|
|
53
|
+
### 1. Define your protocol file
|
|
54
|
+
Create `protocol.json`
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"0": {"funcional": "r2SCAN-3c", "opt": true, "freq": true,"cluster": 5, "comment": "Initial Optimization cluster into 5 families"},
|
|
58
|
+
"1": {"funcional": "wB97X-D4rev", "basis": "def2-QZVPPD", "comment": "Single Point energy evaluation"}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 2. Basic Usage
|
|
64
|
+
```bash
|
|
65
|
+
ensemble_analyzer --ensemble conformers.xyz --protocol protocol.json --output calculation.out --cpu 8 --temperature 298.15
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 3. Restart from Checkpoint
|
|
69
|
+
```bash
|
|
70
|
+
# Automatically resumes from last completed protocol
|
|
71
|
+
ensemble_analyzer --restart
|
|
72
|
+
```
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
### Protocol Parameters
|
|
76
|
+
|
|
77
|
+
| Parameter | Type | Description | Example |
|
|
78
|
+
|-----------|------|-------------|---------|
|
|
79
|
+
| **Calculation Settings** ||||
|
|
80
|
+
| `functional` | str | DFT functional or method | `"B3LYP"`, `"xtb"`, `"HF-3c"` |
|
|
81
|
+
| `basis` | str | Basis set (auto for composite methods) | `"def2-SVP"`, `"def2-TZVP"` |
|
|
82
|
+
| `calculator` | str | QM program | `"orca"` (default), `"gaussian"` |
|
|
83
|
+
| `opt` | bool | Optimize geometry | `true`, `false` |
|
|
84
|
+
| `freq` | bool | Calculate frequencies | `true`, `false` |
|
|
85
|
+
| `mult` | int | Spin multiplicity | `1` (singlet), `2` (doublet) |
|
|
86
|
+
| `charge` | int | Molecular charge | |
|
|
87
|
+
| `calculator` | str | Set the calculator | `orca` (default), `gaussian` |
|
|
88
|
+
| **Pruning Thresholds** ||||
|
|
89
|
+
| `thrG` | float | Energy similarity threshold [kcal/mol] | `3.0`, `5.0` |
|
|
90
|
+
| `thrB` | float | Rotatory constant threshold [cm⁻¹] | `30.0`, `50.0` |
|
|
91
|
+
| `thrGMAX` | float | Energy window cutoff [kcal/mol] | `10.0` |
|
|
92
|
+
| `cluster` | bool/int | Enable clustering | `true` (auto), `5` (fixed) |
|
|
93
|
+
| `no_prune` | bool | Disable pruning | `false` (default) |
|
|
94
|
+
| **Advanced** ||||
|
|
95
|
+
| `solvent` | dict | Implicit solvation | `{"solvent": "water", "model": "SMD"}` |
|
|
96
|
+
| `constrains` | list | Geometry constraints (only on cartesians)| `[1,2]` (fix cartesians) |
|
|
97
|
+
| `monitor_internals` | list | Track bond/angle/dihedral | `[[0,1], [0,1,2]]` |
|
|
98
|
+
| `skip_opt_fail` | bool | Skip failed optimizations | `false` (default) |
|
|
99
|
+
| `skip_retention_rate` | bool | Skip check for retention rate | `false` (default) |
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Standalone CLI applications
|
|
104
|
+
|
|
105
|
+
### Protocol Wizard
|
|
106
|
+
|
|
107
|
+
If you don't want to create from scratch the protocol file, the `enan_protocol_wizard` is an automatic and interactive way to create this essential file.
|
|
108
|
+
It is divided into three different level of configuration: i) basic, where all the essential parameters are asked, ii) intermediate, and iii) advance.
|
|
109
|
+
Feel free to browse all the possible protocol options and parameters.
|
|
110
|
+
|
|
111
|
+
### Regrapher
|
|
112
|
+
|
|
113
|
+
If you want to change the convolution of your graphs, you can edit the setting.json file. Here, all the global settings are present. When finished, the command `enan_regraph` come handy. It re-run the Graph workflow with these new setting and in few time, you'll have your new graphs.
|
|
114
|
+
```bash
|
|
115
|
+
usage: enan_regraph [-h] [-rb READ_BOLTZ] [-no-nm] [-w] [--disable-color] idx [idx ...]
|
|
116
|
+
|
|
117
|
+
positional arguments:
|
|
118
|
+
idx Protocol's number to (re-)generate the graphs
|
|
119
|
+
|
|
120
|
+
options:
|
|
121
|
+
-h, --help show this help message and exit
|
|
122
|
+
-rb READ_BOLTZ, --read-boltz READ_BOLTZ
|
|
123
|
+
Read Boltzmann population from a specific protocol
|
|
124
|
+
-no-nm, --no-nm Do not save the nm graphs
|
|
125
|
+
-w, --weight Show Weighting function
|
|
126
|
+
--disable-color Disable colored output
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Graph Editor
|
|
130
|
+
|
|
131
|
+
All graphs are saved also as a pickle. This file can be reloaded and from there you can modify every single element of the Matplotlib Figure store in it. This requires some programming skills and, especially, time. Here is where `enan_graph_editor` comes to play. It is once again an interactive terminal interface (based both on rich or InquierPy library) where you can change and personalize every pickle. If you have to modify more files at once, a *batch* mode is implemented as well, so to by-pass the limitation of the manual selection of the interactive TUI.
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
usage: enan_graph_editor [-h] [--batch] [--list] [--rename OLD NEW] [--rename-file RENAME_FILE] [--color LABEL COLOR] [--linestyle LABEL STYLE] [--linewidth LABEL WIDTH] [--alpha LABEL ALPHA] [--output OUTPUT] [--format {pickle,png,pdf,svg}] [--preview] [--no-strict]
|
|
135
|
+
[--verbose]
|
|
136
|
+
pickle_file
|
|
137
|
+
|
|
138
|
+
Interactive/batch editor for matplotlib pickles
|
|
139
|
+
|
|
140
|
+
positional arguments:
|
|
141
|
+
pickle_file Matplotlib pickle file
|
|
142
|
+
|
|
143
|
+
options:
|
|
144
|
+
-h, --help show this help message and exit
|
|
145
|
+
--batch, -b Batch mode (non-interactive)
|
|
146
|
+
--no-strict Disable strict validation
|
|
147
|
+
--verbose, -v Verbose output
|
|
148
|
+
|
|
149
|
+
batch mode options:
|
|
150
|
+
--list, -l List labels and exit
|
|
151
|
+
--rename OLD NEW, -r OLD NEW
|
|
152
|
+
Rename label
|
|
153
|
+
--rename-file RENAME_FILE, -rf RENAME_FILE
|
|
154
|
+
Mapping file OLD=NEW
|
|
155
|
+
--color LABEL COLOR, -c LABEL COLOR
|
|
156
|
+
Change colour
|
|
157
|
+
--linestyle LABEL STYLE, -ls LABEL STYLE
|
|
158
|
+
Change line linestyle (e.g., -, --, :, -. )
|
|
159
|
+
--linewidth LABEL WIDTH, -lw LABEL WIDTH
|
|
160
|
+
Change line linewidth (float)
|
|
161
|
+
--alpha LABEL ALPHA, -a LABEL ALPHA
|
|
162
|
+
Change line transparency (0-1)
|
|
163
|
+
--output OUTPUT, -o OUTPUT
|
|
164
|
+
Output file
|
|
165
|
+
--format {pickle,png,pdf,svg}, -f {pickle,png,pdf,svg}
|
|
166
|
+
Output format
|
|
167
|
+
|
|
168
|
+
DEFAULT MODE: Interactive TUI
|
|
169
|
+
python enan_graph_editor plot.pkl
|
|
170
|
+
|
|
171
|
+
BATCH MODE (examples):
|
|
172
|
+
python enan_graph_editor plot.pkl --batch --list
|
|
173
|
+
python enan_graph_editor plot.pkl --batch --rename "Protocol 1" "Proto A"
|
|
174
|
+
python enan_graph_editor plot.pkl --batch --color "Experimental" red --output new.pkl
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
## 🤝 Contributing
|
|
179
|
+
|
|
180
|
+
### Development Workflow
|
|
181
|
+
```bash
|
|
182
|
+
# Fork and clone
|
|
183
|
+
git clone https://github.com/andre-cloud/ensemble_analyzer.git
|
|
184
|
+
cd ensemble_analyzer
|
|
185
|
+
|
|
186
|
+
# Create feature branch
|
|
187
|
+
git checkout -b feature/awesome-feature
|
|
188
|
+
|
|
189
|
+
# Install dev dependencies
|
|
190
|
+
pip install -e .
|
|
191
|
+
|
|
192
|
+
# Commit and push
|
|
193
|
+
git commit -m "Add awesome feature"
|
|
194
|
+
git push origin feature/awesome-feature
|
|
195
|
+
```
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## 📄 License
|
|
199
|
+
|
|
200
|
+
This software is licensed under the MIT-3.0 License. See the LICENSE file for details.
|
|
201
|
+
|
|
202
|
+
## 📞 Support and contact
|
|
203
|
+
|
|
204
|
+
For any questions or support, please contact [by email](mailto:andrea.pellegrini15@unibo.it,paolo.righi@unibo.it).
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "ensemble-analyzer"
|
|
7
|
+
version = '0.0.10a6'
|
|
8
|
+
description = "Automatic Refinement of Conformational Ensemble"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "Andrea Pellegrini", email = "andrea.pellegrini15@unibo.it" },
|
|
15
|
+
{ name = "Paolo Righi", email = "paolo.righi@unibo.it" },
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
maintainers = [
|
|
19
|
+
{ name = "Andrea Pellegrini", email = "andrea.pellegrini15@unibo.it" },
|
|
20
|
+
{ name = "Paolo Righi", email = "paolo.righi@unibo.it" },
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
keywords = [
|
|
24
|
+
"computational-chemistry",
|
|
25
|
+
"conformational-analysis",
|
|
26
|
+
"ensemble-refinement",
|
|
27
|
+
"automatization",
|
|
28
|
+
"ase",
|
|
29
|
+
"quantum-chemistry",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
classifiers = [
|
|
33
|
+
"Development Status :: 4 - Beta",
|
|
34
|
+
"Intended Audience :: Science/Research",
|
|
35
|
+
"Intended Audience :: Developers",
|
|
36
|
+
"Topic :: Scientific/Engineering :: Chemistry",
|
|
37
|
+
"Topic :: Scientific/Engineering :: Physics",
|
|
38
|
+
"License :: OSI Approved :: MIT License",
|
|
39
|
+
"Programming Language :: Python :: 3",
|
|
40
|
+
"Programming Language :: Python :: 3.10",
|
|
41
|
+
"Programming Language :: Python :: 3.11",
|
|
42
|
+
"Programming Language :: Python :: 3.12",
|
|
43
|
+
"Programming Language :: Python :: 3.13",
|
|
44
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
45
|
+
"Operating System :: OS Independent",
|
|
46
|
+
"Typing :: Typed",
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
dependencies = [
|
|
50
|
+
"numpy==2.2.0",
|
|
51
|
+
"scipy==1.16.3",
|
|
52
|
+
"matplotlib==3.10.7",
|
|
53
|
+
"scikit-learn==1.7.2",
|
|
54
|
+
"ase==3.24.0",
|
|
55
|
+
"numba==0.61.2",
|
|
56
|
+
"tabulate==0.9.0",
|
|
57
|
+
"InquirerPy==0.3.4",
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
[project.scripts]
|
|
61
|
+
ensemble_analyzer = "ensemble_analyzer.launch:main"
|
|
62
|
+
enan_regraph = "ensemble_analyzer.cli.regraph:main"
|
|
63
|
+
enan_graph_editor = "ensemble_analyzer.cli.pickle_editor.cli:main"
|
|
64
|
+
enan_protocol_wizard = "ensemble_analyzer.cli.protocol_wizard:main"
|
|
65
|
+
enan_get_energies = "ensemble_analyzer.cli.get_av_energy:main"
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
[tool.setuptools]
|
|
69
|
+
include-package-data = true
|
|
70
|
+
|
|
71
|
+
[tool.setuptools.package-data]
|
|
72
|
+
ensemble_analyzer = ["parameters_file/*"]
|
|
73
|
+
|
|
74
|
+
[project.urls]
|
|
75
|
+
Homepage = "https://github.com/andre-cloud/ensemble_analyzer"
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
import pkgutil
|
|
3
|
+
|
|
4
|
+
# Importa automaticamente tutti i moduli nella cartella
|
|
5
|
+
for module_info in pkgutil.iter_modules(__path__):
|
|
6
|
+
if module_info.name != "base": # evita di ricaricare base.py
|
|
7
|
+
importlib.import_module(f"{__name__}.{module_info.name}")
|
|
8
|
+
|
|
9
|
+
# Espone il registro globale
|
|
10
|
+
from .base import CALCULATOR_REGISTRY, BaseCalc, register_calculator
|
|
11
|
+
|
|
12
|
+
__all__ = ["CALCULATOR_REGISTRY", "BaseCalc", "register_calculator"]
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from ase.calculators.gaussian import Gaussian
|
|
3
|
+
from ensemble_analyzer._calculators.base import BaseCalc, register_calculator
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@register_calculator("gaussian")
|
|
7
|
+
class GaussianCalc(BaseCalc):
|
|
8
|
+
"""
|
|
9
|
+
ASE-compatible Gaussian calculator wrapper.
|
|
10
|
+
This class follows the same structure as OrcaCalc,
|
|
11
|
+
encapsulating the logic for SP, OPT, and FREQ calculations.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def common_str(self):
|
|
15
|
+
"""
|
|
16
|
+
Build the common Gaussian input string (route section)
|
|
17
|
+
based on the Protocol parameters.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
# Construct solvent model (if any)
|
|
21
|
+
solv = ""
|
|
22
|
+
if self.protocol.solvent:
|
|
23
|
+
if self.protocol.solvent.smd:
|
|
24
|
+
solv = f" SCRF=(SMD,Solvent={self.protocol.solvent.solvent})"
|
|
25
|
+
else:
|
|
26
|
+
solv = f" SCRF=(CPCM,Solvent={self.protocol.solvent.solvent})"
|
|
27
|
+
|
|
28
|
+
# Basic route section
|
|
29
|
+
route = f"# {self.protocol.functional}/{self.protocol.basis}{solv}"
|
|
30
|
+
|
|
31
|
+
# Add user-specified custom input
|
|
32
|
+
if self.protocol.add_input.strip():
|
|
33
|
+
route += " " + self.protocol.add_input.strip()
|
|
34
|
+
|
|
35
|
+
if self.protocol.read_orbitals:
|
|
36
|
+
route += " guess=read"
|
|
37
|
+
|
|
38
|
+
# Default options: no population output
|
|
39
|
+
# route += " pop=none"
|
|
40
|
+
|
|
41
|
+
return route
|
|
42
|
+
|
|
43
|
+
def _std_calc(self):
|
|
44
|
+
route = self.common_str()
|
|
45
|
+
|
|
46
|
+
calc = Gaussian(
|
|
47
|
+
label="gaussian",
|
|
48
|
+
output_type='N',
|
|
49
|
+
mem=f"{self.cpu*2}GB",
|
|
50
|
+
extra=route,
|
|
51
|
+
charge=self.protocol.charge,
|
|
52
|
+
mult=self.protocol.mult,
|
|
53
|
+
nprocshared=self.cpu,
|
|
54
|
+
)
|
|
55
|
+
if self.protocol.read_orbitals:
|
|
56
|
+
calc.oldchk = (
|
|
57
|
+
f"{self.conf.folder}/protocol_{self.protocol.read_orbitals}.chk"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
return calc, "gaussian"
|
|
61
|
+
|
|
62
|
+
def single_point(self):
|
|
63
|
+
|
|
64
|
+
calc, label = self._std_calc()
|
|
65
|
+
return calc, label
|
|
66
|
+
|
|
67
|
+
def optimisation(self):
|
|
68
|
+
|
|
69
|
+
calc, label = self._std_calc()
|
|
70
|
+
if not self.protocol.constrains:
|
|
71
|
+
calc.parameters["extra"] += " opt"
|
|
72
|
+
else:
|
|
73
|
+
calc.parameters["extra"] += " opt=(modredudant)"
|
|
74
|
+
redundant = "\n".join([f"X {i+1} F" for i in self.protocol.constrains])
|
|
75
|
+
# Counting in gaussian starts at 1
|
|
76
|
+
|
|
77
|
+
if calc.parameters.get("addsec"):
|
|
78
|
+
calc.parameters["addsec"] += redundant
|
|
79
|
+
else:
|
|
80
|
+
calc.parameters["addsec"] = redundant
|
|
81
|
+
|
|
82
|
+
if self.protocol.freq:
|
|
83
|
+
calc.parameters["extra"] += " freq=(HPModes,vcd)"
|
|
84
|
+
|
|
85
|
+
return calc, label
|
|
86
|
+
|
|
87
|
+
def frequency(self):
|
|
88
|
+
|
|
89
|
+
calc, label = self._std_calc()
|
|
90
|
+
calc.parameters["extra"] += " freq=(HPModes,vcd)"
|
|
91
|
+
return calc, label
|