ensemble-analyzer 1.2__tar.gz → 1.2.1__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.
- {ensemble_analyzer-1.2/src/ensemble_analyzer.egg-info → ensemble_analyzer-1.2.1}/PKG-INFO +1 -1
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/pyproject.toml +1 -1
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/parsers/gaussian.py +44 -52
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/parsers/orca.py +35 -57
- ensemble_analyzer-1.2.1/src/ensemble_analyzer/parsers/vibrations.py +228 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1/src/ensemble_analyzer.egg-info}/PKG-INFO +1 -1
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer.egg-info/SOURCES.txt +1 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/LICENSE +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/README.md +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/setup.cfg +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/enan_calculators/__init__.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/enan_calculators/_aimnet.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/enan_calculators/_fairchem.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/enan_calculators/_gaussian.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/enan_calculators/_mace.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/enan_calculators/_ml_inference.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/enan_calculators/_models.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/enan_calculators/_nwchem.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/enan_calculators/_orca.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/enan_calculators/_skala.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/enan_calculators/_tblite.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/enan_calculators/_uma.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/__init__.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/__main__.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_clustering/__init__.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_clustering/cluster_config.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_clustering/cluster_manager.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_logger/__init__.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_logger/create_log.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_logger/formatter.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_logger/logger.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_managers/__init__.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_managers/calculation_config.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_managers/calculation_executor.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_managers/calculator_orchestration.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_managers/checkpoint_manager.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_managers/prism_backend.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_managers/protocol_executor.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_managers/protocol_manager.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_managers/pruning_manager.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_parser_arguments.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_parser_parameter.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_spectral/__init__.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_spectral/base.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_spectral/comp_electronic.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_spectral/comp_vibronic.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_spectral/compare.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_spectral/experimental.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_spectral/graph_default.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_title.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/api.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/__init__.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/_ml_base.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/aimnet.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/base.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/fairchem.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/gaussian.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/mace.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/nwchem.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/orca.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/skala_calc.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/tblite.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/uma.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/__init__.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/check_setup.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/clustering.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/get_av_energy.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/pickle_editor/__init__.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/pickle_editor/cli.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/pickle_editor/core.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/pickle_editor/tui.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/protocol_wizard/__init__.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/protocol_wizard/app_state.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/protocol_wizard/fields.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/protocol_wizard/main.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/protocol_wizard/screens.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/protocol_wizard/templates.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/regraph.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/clustering.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/conformer/__init__.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/conformer/conformer.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/conformer/energy_data.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/conformer/spectral_data.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/constants.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/ensemble_io.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/graph.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/io_utils.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/launch.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/mode_analysis.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/parameters_file/basis_sets +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/parameters_file/default_protocol.json +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/parameters_file/default_threshold.json +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/parameters_file/functionals +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/parsers/__init__.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/parsers/base.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/parsers/nwchem.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/protocol/__init__.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/protocol/protocol.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/protocol/solvent.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/rrho.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/validators.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer.egg-info/dependency_links.txt +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer.egg-info/entry_points.txt +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer.egg-info/requires.txt +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer.egg-info/top_level.txt +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/test/test_api.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/test/test_clustering.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/test/test_ensemble_io.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/test/test_high_level.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/test/test_io_utils.py +0 -0
- {ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/test/test_mode_analysis.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ensemble-analyzer
|
|
3
|
-
Version: 1.2
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: Automatic Refinement of Conformational Ensemble
|
|
5
5
|
Author-email: Andrea Pellegrini <andrea.pellegrini15@unibo.it>, Paolo Righi <paolo.righi@unibo.it>, Andrea Mazzanti <andrea.mazzanti@unibo.it>, Michele Mancinelli <michele.mancinelli@unibo.it>
|
|
6
6
|
Maintainer-email: Andrea Pellegrini <andrea.pellegrini15@unibo.it>, Paolo Righi <paolo.righi@unibo.it>
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
3
|
from ensemble_analyzer.parsers.base import BaseParser, register_parser
|
|
4
|
+
from ensemble_analyzer.parsers.vibrations import (
|
|
5
|
+
gaussian_get_freq, gaussian_get_ir_intensities, gaussian_get_normal_modes,
|
|
6
|
+
gaussian_align_normal_modes, to_displacements,
|
|
7
|
+
)
|
|
4
8
|
|
|
5
9
|
import re
|
|
6
10
|
import numpy as np
|
|
@@ -29,6 +33,12 @@ class GaussianParser(BaseParser):
|
|
|
29
33
|
"start_spec": "Excited states from",
|
|
30
34
|
"e_freq": "\n\n\n",
|
|
31
35
|
"idx_freq": 1, # index for frequency in frequency table
|
|
36
|
+
# frequency section (same keys as frogchem regex_gaussian)
|
|
37
|
+
"freq_section": "Harmonic frequencies (cm**-1), IR intensities (KM/Mole), Raman scattering",
|
|
38
|
+
"freq_end": "\n\n\n",
|
|
39
|
+
"freq_pattern": r'Frequencies\s*--\s*((?:[+-]?\d+\.\d+\s*)+)',
|
|
40
|
+
"ir_pattern": r'IR Inten\s*--\s*((?:[+-]?\d+\.\d+\s*)+)',
|
|
41
|
+
"rot_pattern": r'Rot\. str\.\s*--\s*((?:[+-]?\d+\.\d+\s*)+)',
|
|
32
42
|
"opt_done": "Optimization completed",
|
|
33
43
|
"geom_start": """Input orientation:
|
|
34
44
|
---------------------------------------------------------------------
|
|
@@ -59,68 +69,50 @@ class GaussianParser(BaseParser):
|
|
|
59
69
|
|
|
60
70
|
def parse_freq(self) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
61
71
|
"""
|
|
62
|
-
Parse vibrational frequencies, IR and VCD intensities.
|
|
72
|
+
Parse vibrational frequencies, IR and VCD intensities (FROGChem parser).
|
|
63
73
|
|
|
64
74
|
Returns:
|
|
65
75
|
Tuple: (Frequencies array, IR spectrum array, VCD spectrum array).
|
|
66
76
|
"""
|
|
67
77
|
|
|
68
|
-
if not self.regex['
|
|
78
|
+
if not self.regex['freq_section'] in self.fl:
|
|
69
79
|
return np.array([]), np.zeros(shape=(1,2)), np.zeros(shape=(1,2))
|
|
70
|
-
|
|
71
|
-
fl = self.get_filtered_text(start=self.regex['s_freq'], end=self.regex['e_freq'])
|
|
72
|
-
freq_pattern = re.compile(r'Frequencies\s*--\s*((?:[+-]?\d+\.\d+\s*)+)')
|
|
73
|
-
ir_pattern = re.compile(r'IR Inten\s*--\s*((?:[+-]?\d+\.\d+\s*)+)')
|
|
74
|
-
rot_pattern = re.compile(r'Rot\. str\.\s*--\s*((?:[+-]?\d+\.\d+\s*)+)')
|
|
75
80
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
ir_inten = np.array([float(x) for m in ir_pattern.findall(fl) for x in m.split()])
|
|
79
|
-
rot_str = np.array([float(x) for m in rot_pattern.findall(fl) for x in m.split()])
|
|
81
|
+
frequencies = gaussian_get_freq(self.fl, self.regex)
|
|
82
|
+
ir = gaussian_get_ir_intensities(self.fl, self.regex)
|
|
80
83
|
|
|
81
|
-
|
|
84
|
+
# VCD: rotational strengths, only printed with freq=VCD
|
|
85
|
+
fl = self.get_filtered_text(start=self.regex['freq_section'], end=self.regex['freq_end'])
|
|
86
|
+
rot_str = np.array([float(x) for m in re.findall(self.regex['rot_pattern'], fl) for x in m.split()])
|
|
87
|
+
if len(rot_str) == len(frequencies) and len(rot_str) > 0:
|
|
88
|
+
vcd = np.column_stack((frequencies, rot_str))
|
|
89
|
+
else:
|
|
90
|
+
vcd = np.zeros(shape=(1, 2))
|
|
91
|
+
|
|
92
|
+
return frequencies, ir, vcd
|
|
82
93
|
|
|
83
94
|
def parse_normal_modes(self, n_atoms: int) -> np.ndarray:
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
idx += 1
|
|
106
|
-
mode_disps = np.zeros((n_freq, n_atoms, 3))
|
|
107
|
-
for i in range(idx, min(idx + n_atoms, len(lines))):
|
|
108
|
-
line = lines[i].strip()
|
|
109
|
-
if not line or not re.match(r'^\d+\s+\d+', line):
|
|
110
|
-
break
|
|
111
|
-
parts_line = line.split()
|
|
112
|
-
if len(parts_line) < 2 + 3 * n_freq:
|
|
113
|
-
continue
|
|
114
|
-
atom_idx = int(parts_line[0]) - 1
|
|
115
|
-
vals = [float(x) for x in parts_line[2:]]
|
|
116
|
-
for k in range(n_freq):
|
|
117
|
-
mode_disps[k, atom_idx, 0] = vals[3 * k]
|
|
118
|
-
mode_disps[k, atom_idx, 1] = vals[3 * k + 1]
|
|
119
|
-
mode_disps[k, atom_idx, 2] = vals[3 * k + 2]
|
|
120
|
-
all_modes.append(mode_disps)
|
|
121
|
-
if not all_modes:
|
|
122
|
-
return np.empty((0, n_atoms, 3))
|
|
123
|
-
return np.vstack(all_modes)
|
|
95
|
+
"""Cartesian displacement vectors of the vibrational modes (FROGChem parser).
|
|
96
|
+
|
|
97
|
+
Gaussian prints them in the standard orientation; they are rotated onto the input
|
|
98
|
+
orientation, i.e. the frame of parse_geom.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
np.ndarray: (n_modes, n_atoms, 3), same order as the frequencies of parse_freq.
|
|
102
|
+
Empty (0, n_atoms, 3) array when the frequency section is missing.
|
|
103
|
+
"""
|
|
104
|
+
empty = np.empty((0, n_atoms, 3))
|
|
105
|
+
try:
|
|
106
|
+
matrix = gaussian_get_normal_modes(self.fl, self.regex, N=3 * n_atoms)
|
|
107
|
+
except ValueError:
|
|
108
|
+
return empty
|
|
109
|
+
except Exception as err:
|
|
110
|
+
self.log.warning(f"Normal modes could not be parsed: {err}")
|
|
111
|
+
return empty
|
|
112
|
+
if matrix.shape[1] == 0:
|
|
113
|
+
return empty
|
|
114
|
+
matrix = gaussian_align_normal_modes(self.fl, matrix)
|
|
115
|
+
return to_displacements(matrix, n_atoms)
|
|
124
116
|
|
|
125
117
|
def parse_tddft(self) -> Tuple[np.ndarray, np.ndarray]:
|
|
126
118
|
"""
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
from ensemble_analyzer.parsers.base import BaseParser, register_parser
|
|
3
3
|
from ensemble_analyzer.constants import FACTOR_EV_CM_1
|
|
4
|
+
from ensemble_analyzer.parsers.vibrations import orca_get_freq, orca_get_normal_modes, to_displacements
|
|
4
5
|
|
|
5
6
|
import re
|
|
6
7
|
import numpy as np
|
|
@@ -50,6 +51,9 @@ class OrcaParser(BaseParser):
|
|
|
50
51
|
"s_freq": "VIBRATIONAL FREQUENCIES",
|
|
51
52
|
"e_freq": "------------",
|
|
52
53
|
"idx_freq": 1, # index for frequency in frequency table
|
|
54
|
+
# frequency / normal-mode blocks (same keys as frogchem regex_ORCA)
|
|
55
|
+
"frequency": r'VIBRATIONAL FREQUENCIES([\S\s]*?)\n\n\n',
|
|
56
|
+
"normal_modes": r'NORMAL MODES([\S\s]*?)\n\n\n',
|
|
53
57
|
"opt_done": "THE OPTIMIZATION HAS CONVERGED",
|
|
54
58
|
"geom_start": """CARTESIAN COORDINATES (ANGSTROEM)
|
|
55
59
|
---------------------------------""",
|
|
@@ -88,6 +92,9 @@ State Energy Wavelength R MX MY MZ
|
|
|
88
92
|
"s_freq": "VIBRATIONAL FREQUENCIES",
|
|
89
93
|
"e_freq": "------------",
|
|
90
94
|
"idx_freq": 1, # index for frequency in frequency table
|
|
95
|
+
# frequency / normal-mode blocks (same keys as frogchem regex_ORCA)
|
|
96
|
+
"frequency": r'VIBRATIONAL FREQUENCIES([\S\s]*?)\n\n\n',
|
|
97
|
+
"normal_modes": r'NORMAL MODES([\S\s]*?)\n\n\n',
|
|
91
98
|
"opt_done": "THE OPTIMIZATION HAS CONVERGED",
|
|
92
99
|
"geom_start": """CARTESIAN COORDINATES (ANGSTROEM)
|
|
93
100
|
---------------------------------""",
|
|
@@ -136,13 +143,9 @@ State Energy Wavelength R MX MY MZ
|
|
|
136
143
|
if not self.regex['s_freq'] in self.fl:
|
|
137
144
|
return np.array([]), np.zeros(shape=(1,2)), np.zeros(shape=(1,2))
|
|
138
145
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
# freq
|
|
143
|
-
freq = np.array(re.findall(pattern, fl, flags=re.MULTILINE), dtype=float)
|
|
144
|
-
self._freq_mask = freq != 0
|
|
145
|
-
freq = freq[self._freq_mask]
|
|
146
|
+
# freq (FROGChem parser): translations/rotations are printed as zeros and dropped here
|
|
147
|
+
freq = self._all_freq()
|
|
148
|
+
freq = freq[freq != 0]
|
|
146
149
|
|
|
147
150
|
# IR
|
|
148
151
|
if self.regex['s_IR'] not in self.fl:
|
|
@@ -160,58 +163,33 @@ State Energy Wavelength R MX MY MZ
|
|
|
160
163
|
|
|
161
164
|
return freq, ir, vcd
|
|
162
165
|
|
|
166
|
+
def _all_freq(self) -> np.ndarray:
|
|
167
|
+
"""All ORCA frequencies (cm-1), translations/rotations included as zeros."""
|
|
168
|
+
if not re.search(self.regex['frequency'], self.fl):
|
|
169
|
+
return np.array([])
|
|
170
|
+
return orca_get_freq(self.fl, self.regex)[1]
|
|
171
|
+
|
|
163
172
|
def parse_normal_modes(self, n_atoms: int) -> np.ndarray:
|
|
164
|
-
|
|
165
|
-
|
|
173
|
+
"""Cartesian displacement vectors of the vibrational modes (FROGChem parser).
|
|
174
|
+
|
|
175
|
+
Returns:
|
|
176
|
+
np.ndarray: (n_modes, n_atoms, 3), same order as the frequencies of parse_freq
|
|
177
|
+
(translation/rotation modes, i.e. zero frequencies, are dropped). Empty
|
|
178
|
+
(0, n_atoms, 3) array when the NORMAL MODES block is missing.
|
|
179
|
+
"""
|
|
180
|
+
empty = np.empty((0, n_atoms, 3))
|
|
166
181
|
try:
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if cols and cols[-1] > max_col:
|
|
179
|
-
max_col = cols[-1]
|
|
180
|
-
if max_col < 0:
|
|
181
|
-
return np.empty((0, n_atoms, 3))
|
|
182
|
-
matrix = np.zeros((n_total, max_col + 1))
|
|
183
|
-
current_columns = []
|
|
184
|
-
for line in lines:
|
|
185
|
-
stripped = line.strip()
|
|
186
|
-
if not stripped or stripped.startswith("-"):
|
|
187
|
-
continue
|
|
188
|
-
header_match = re.match(r'^\s*(\d+(?:\s+\d+)*)\s*$', stripped)
|
|
189
|
-
if header_match:
|
|
190
|
-
current_columns = [int(x) for x in header_match.group(1).split()]
|
|
191
|
-
continue
|
|
192
|
-
data_match = re.match(
|
|
193
|
-
r'^\s*(\d+)\s+((?:[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?\s*)+)', stripped
|
|
194
|
-
)
|
|
195
|
-
if data_match and current_columns:
|
|
196
|
-
row_idx = int(data_match.group(1))
|
|
197
|
-
coeff_str = data_match.group(2)
|
|
198
|
-
coeffs = [float(c) for c in re.findall(
|
|
199
|
-
r'[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?', coeff_str
|
|
200
|
-
)]
|
|
201
|
-
for i, c in enumerate(coeffs):
|
|
202
|
-
if i < len(current_columns) and row_idx < n_total:
|
|
203
|
-
col = current_columns[i]
|
|
204
|
-
matrix[row_idx, col] = c
|
|
205
|
-
n_modes = matrix.shape[1]
|
|
206
|
-
all_modes = np.zeros((n_modes, n_atoms, 3))
|
|
207
|
-
for mode_idx in range(n_modes):
|
|
208
|
-
vec = matrix[:n_total, mode_idx]
|
|
209
|
-
all_modes[mode_idx] = vec.reshape(n_atoms, 3)
|
|
210
|
-
if hasattr(self, '_freq_mask') and self._freq_mask is not None and len(self._freq_mask) == len(all_modes):
|
|
211
|
-
all_modes = all_modes[self._freq_mask]
|
|
212
|
-
return all_modes
|
|
213
|
-
except Exception:
|
|
214
|
-
return np.empty((0, n_atoms, 3))
|
|
182
|
+
matrix = orca_get_normal_modes(self.fl, self.regex, N=3 * n_atoms)
|
|
183
|
+
except ValueError:
|
|
184
|
+
return empty
|
|
185
|
+
except Exception as err:
|
|
186
|
+
self.log.warning(f"Normal modes could not be parsed: {err}")
|
|
187
|
+
return empty
|
|
188
|
+
modes = to_displacements(matrix, n_atoms)
|
|
189
|
+
freq = self._all_freq()
|
|
190
|
+
if len(freq) == len(modes):
|
|
191
|
+
modes = modes[freq != 0]
|
|
192
|
+
return modes
|
|
215
193
|
|
|
216
194
|
def parse_tddft(self) -> Tuple[np.ndarray, np.ndarray]:
|
|
217
195
|
"""
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"""Vibrational-analysis parsers shared with FROGChem (frogchem).
|
|
2
|
+
|
|
3
|
+
COPY of the FROGChem frequency parsers -- keep in sync with:
|
|
4
|
+
frogchem/orca_parser/hessian.py get_freq, get_normal_modes, to_displacements
|
|
5
|
+
frogchem/gaussian_parser/hessian.py get_freq, get_ir_intensities, get_normal_modes,
|
|
6
|
+
align_normal_modes (+ private helpers)
|
|
7
|
+
Functions are renamed with an ``orca_`` / ``gaussian_`` prefix; bodies are identical.
|
|
8
|
+
They take the whole output text ``fl`` and a regex dict ``reg`` with the FROGChem keys.
|
|
9
|
+
|
|
10
|
+
Layout of the normal modes returned by ``*_get_normal_modes``: (3N, n_modes), rows
|
|
11
|
+
x0, y0, z0, x1, ...; ``to_displacements`` turns it into (n_modes, N, 3) displacement vectors.
|
|
12
|
+
"""
|
|
13
|
+
import re
|
|
14
|
+
import logging
|
|
15
|
+
import numpy as np
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# ---------------------------------------------------------------------------
|
|
21
|
+
# ORCA (frogchem/orca_parser/hessian.py)
|
|
22
|
+
# ---------------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
def orca_get_freq(fl, reg):
|
|
25
|
+
"""Mode numbers and frequencies (cm-1) of the last VIBRATIONAL FREQUENCIES block.
|
|
26
|
+
|
|
27
|
+
Translations/rotations are included as zero frequencies, imaginary modes are negative.
|
|
28
|
+
|
|
29
|
+
NOTE: copied verbatim in ensemble_analyzer/parsers/vibrations.py (orca_get_freq).
|
|
30
|
+
"""
|
|
31
|
+
f_ = re.findall(reg['frequency'], fl)[-1]
|
|
32
|
+
match = np.array(re.findall(r'(\d+):\s+(-?[\d.]+)\s+cm\*\*-1*', f_), dtype=np.float64)
|
|
33
|
+
numbers_mode, freq = match[:, 0].astype(int), match[:, 1]
|
|
34
|
+
return numbers_mode, freq.astype(np.float64)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def orca_get_normal_modes(fl, reg, N):
|
|
38
|
+
"""Cartesian displacement vectors of the NORMAL MODES block.
|
|
39
|
+
|
|
40
|
+
Returns an (N, n_modes) matrix: N = 3 * n_atoms rows (x0, y0, z0, x1, ...), one column per
|
|
41
|
+
mode as numbered by ORCA (translations/rotations included, so n_modes = N for a full Hessian).
|
|
42
|
+
The number of columns is read from the block headers.
|
|
43
|
+
|
|
44
|
+
NOTE: copied verbatim in ensemble_analyzer/parsers/vibrations.py (orca_get_normal_modes).
|
|
45
|
+
Keep the two copies in sync.
|
|
46
|
+
"""
|
|
47
|
+
matches = re.findall(reg['normal_modes'], fl, re.DOTALL)
|
|
48
|
+
if not matches:
|
|
49
|
+
raise ValueError("Pattern 'normal_modes' non trovato nel file")
|
|
50
|
+
|
|
51
|
+
target_text = matches[-1].split('\n\n')[-1]
|
|
52
|
+
header_pattern = r'^\s*(\d+(?:\s+\d+)*)\s*$'
|
|
53
|
+
data_pattern = r'^\s*(\d+)\s+((?:[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?\s*)+)'
|
|
54
|
+
|
|
55
|
+
lines = target_text.strip().split('\n')
|
|
56
|
+
n_cols = max(
|
|
57
|
+
(int(line.split()[-1]) + 1 for line in lines if re.match(header_pattern, line.strip())),
|
|
58
|
+
default=N,
|
|
59
|
+
)
|
|
60
|
+
matrix = np.zeros((N, n_cols))
|
|
61
|
+
current_columns = []
|
|
62
|
+
|
|
63
|
+
for line in lines:
|
|
64
|
+
line = line.strip()
|
|
65
|
+
if not line:
|
|
66
|
+
continue
|
|
67
|
+
|
|
68
|
+
header_match = re.match(header_pattern, line)
|
|
69
|
+
if header_match:
|
|
70
|
+
current_columns = [int(x) for x in header_match.group(1).split()]
|
|
71
|
+
continue
|
|
72
|
+
|
|
73
|
+
data_match = re.match(data_pattern, line)
|
|
74
|
+
if data_match and current_columns:
|
|
75
|
+
try:
|
|
76
|
+
row_idx = int(data_match.group(1))
|
|
77
|
+
coefficients_str = data_match.group(2)
|
|
78
|
+
coefficients = re.findall(r'[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?', coefficients_str)
|
|
79
|
+
coefficients = [float(c) for c in coefficients]
|
|
80
|
+
|
|
81
|
+
for i, coeff in enumerate(coefficients):
|
|
82
|
+
if i < len(current_columns) and row_idx < N and current_columns[i] < n_cols:
|
|
83
|
+
matrix[row_idx, current_columns[i]] = coeff
|
|
84
|
+
except (ValueError, IndexError) as e:
|
|
85
|
+
logger.warning("Errore processando riga dati '%s': %s", line, e)
|
|
86
|
+
continue
|
|
87
|
+
|
|
88
|
+
return matrix
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def to_displacements(normal_modes, n_atoms):
|
|
92
|
+
"""(3N, n_modes) normal-mode matrix -> (n_modes, n_atoms, 3) displacement vectors.
|
|
93
|
+
|
|
94
|
+
NOTE: copied verbatim in ensemble_analyzer/parsers/vibrations.py.
|
|
95
|
+
"""
|
|
96
|
+
normal_modes = np.asarray(normal_modes, dtype=np.float64)
|
|
97
|
+
return np.ascontiguousarray(normal_modes[:3 * n_atoms].T).reshape(-1, n_atoms, 3)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# ---------------------------------------------------------------------------
|
|
101
|
+
# Gaussian (frogchem/gaussian_parser/hessian.py)
|
|
102
|
+
# ---------------------------------------------------------------------------
|
|
103
|
+
|
|
104
|
+
_ORIENT_ROW = re.compile(r'^\s*\d+\s+(\d+)\s+(?:-?\d+\s+)?(-?\d+\.\d+)\s+(-?\d+\.\d+)\s+(-?\d+\.\d+)\s*$')
|
|
105
|
+
_MODE_ROW = re.compile(r'^\s*(\d+)\s+(\d+)((?:\s+[-+]?\d+\.\d+)+)\s*$')
|
|
106
|
+
_FLOAT = re.compile(r'[-+]?\d+\.\d+')
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _freq_block(fl, reg):
|
|
110
|
+
# last frequency section (with freq=HPModes the standard 3-column section is printed last)
|
|
111
|
+
return fl.split(reg['freq_section'])[-1].split(reg['freq_end'])[0]
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def gaussian_get_freq(fl, reg):
|
|
115
|
+
if reg['freq_section'] not in fl:
|
|
116
|
+
return np.array([])
|
|
117
|
+
|
|
118
|
+
block = _freq_block(fl, reg)
|
|
119
|
+
freq = np.array([float(x) for m in re.findall(reg['freq_pattern'], block) for x in m.split()])
|
|
120
|
+
return freq
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def gaussian_get_ir_intensities(fl, reg):
|
|
124
|
+
if reg['freq_section'] not in fl:
|
|
125
|
+
return np.zeros(shape=(1, 2))
|
|
126
|
+
|
|
127
|
+
block = _freq_block(fl, reg)
|
|
128
|
+
freq = np.array([float(x) for m in re.findall(reg['freq_pattern'], block) for x in m.split()])
|
|
129
|
+
ir = np.array([float(x) for m in re.findall(reg['ir_pattern'], block) for x in m.split()])
|
|
130
|
+
if len(freq) == 0 or len(ir) == 0:
|
|
131
|
+
return np.zeros(shape=(1, 2))
|
|
132
|
+
return np.column_stack((freq, ir))
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def gaussian_get_normal_modes(fl, reg, N):
|
|
136
|
+
"""Cartesian displacement vectors of the normal modes, in Gaussian's *standard orientation*.
|
|
137
|
+
|
|
138
|
+
Returns an (N, n_modes) matrix, N = 3 * n_atoms rows (x0, y0, z0, x1, ...), one column per
|
|
139
|
+
vibrational mode in the order of get_freq (same layout as orca_parser.hessian.get_normal_modes,
|
|
140
|
+
but Gaussian prints no translations/rotations). Read from the standard 3-modes-per-block table
|
|
141
|
+
('Atom AN X Y Z ...'). Use align_normal_modes to express them in the frame of the parsed
|
|
142
|
+
geometry. Raises ValueError when the file has no frequency section.
|
|
143
|
+
"""
|
|
144
|
+
if reg['freq_section'] not in fl:
|
|
145
|
+
raise ValueError("Frequency section not found")
|
|
146
|
+
|
|
147
|
+
columns = [] # one (N,) vector per mode
|
|
148
|
+
block_modes = 0 # modes in the current block (from its 'Frequencies --' line)
|
|
149
|
+
in_table = False
|
|
150
|
+
for line in _freq_block(fl, reg).splitlines():
|
|
151
|
+
freq_match = re.search(reg['freq_pattern'], line)
|
|
152
|
+
if freq_match:
|
|
153
|
+
block_modes = len(freq_match.group(1).split())
|
|
154
|
+
block = [np.zeros(N) for _ in range(block_modes)]
|
|
155
|
+
columns.extend(block)
|
|
156
|
+
in_table = False
|
|
157
|
+
continue
|
|
158
|
+
if block_modes and line.split()[:2] == ['Atom', 'AN']:
|
|
159
|
+
in_table = True
|
|
160
|
+
continue
|
|
161
|
+
if not in_table:
|
|
162
|
+
continue
|
|
163
|
+
row = _MODE_ROW.match(line)
|
|
164
|
+
if row is None:
|
|
165
|
+
in_table = False
|
|
166
|
+
continue
|
|
167
|
+
atom = int(row.group(1)) - 1
|
|
168
|
+
values = [float(x) for x in _FLOAT.findall(row.group(3))]
|
|
169
|
+
if len(values) != 3 * block_modes or 3 * atom + 2 >= N:
|
|
170
|
+
logger.warning("Skipping malformed normal-mode row: %r", line)
|
|
171
|
+
continue
|
|
172
|
+
for k in range(block_modes):
|
|
173
|
+
block[k][3 * atom:3 * atom + 3] = values[3 * k:3 * k + 3]
|
|
174
|
+
|
|
175
|
+
if not columns:
|
|
176
|
+
return np.zeros((N, 0))
|
|
177
|
+
return np.column_stack(columns)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def _last_orientation(fl, header):
|
|
181
|
+
"""Coordinates (Å) of the last orientation table with the given header, or None."""
|
|
182
|
+
if header not in fl:
|
|
183
|
+
return None
|
|
184
|
+
coords, dashes = [], 0
|
|
185
|
+
for line in fl.split(header)[-1].splitlines():
|
|
186
|
+
if line.strip().startswith('---'):
|
|
187
|
+
dashes += 1
|
|
188
|
+
if dashes >= 3:
|
|
189
|
+
break
|
|
190
|
+
continue
|
|
191
|
+
if dashes == 2:
|
|
192
|
+
match = _ORIENT_ROW.match(line)
|
|
193
|
+
if not match:
|
|
194
|
+
break
|
|
195
|
+
coords.append([float(match.group(i)) for i in (2, 3, 4)])
|
|
196
|
+
return np.array(coords, dtype=float) if coords else None
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _kabsch(P, Q):
|
|
200
|
+
"""Proper rotation R and RMSD (Å) such that (P - <P>) @ R ≈ (Q - <Q>)."""
|
|
201
|
+
Pc, Qc = P - P.mean(axis=0), Q - Q.mean(axis=0)
|
|
202
|
+
U, _, Vt = np.linalg.svd(Pc.T @ Qc)
|
|
203
|
+
d = np.sign(np.linalg.det(U @ Vt))
|
|
204
|
+
R = U @ np.diag([1.0, 1.0, d]) @ Vt
|
|
205
|
+
rmsd = float(np.sqrt(np.mean(np.sum((Pc @ R - Qc) ** 2, axis=1))))
|
|
206
|
+
return R, rmsd
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def gaussian_align_normal_modes(fl, normal_modes, target='Input orientation:', source='Standard orientation:', tol=1e-2):
|
|
210
|
+
"""Rotate (3N, n_modes) normal modes from the standard orientation to the `target` frame.
|
|
211
|
+
|
|
212
|
+
Gaussian prints the normal coordinates in the standard orientation, while the parsers return
|
|
213
|
+
the input-orientation geometry when it is printed. The rotation is the Kabsch fit of the last
|
|
214
|
+
standard-orientation table onto the last `target` table; when one of the two tables is
|
|
215
|
+
missing (e.g. NoSymm jobs print only the input orientation) the modes are returned unchanged.
|
|
216
|
+
"""
|
|
217
|
+
std = _last_orientation(fl, source)
|
|
218
|
+
tgt = _last_orientation(fl, target)
|
|
219
|
+
if std is None or tgt is None or std.shape != tgt.shape or normal_modes.shape[0] != std.size:
|
|
220
|
+
return normal_modes
|
|
221
|
+
R, rmsd = _kabsch(std, tgt)
|
|
222
|
+
if rmsd > tol:
|
|
223
|
+
logger.warning("Standard and input orientations do not superimpose (RMSD %.3g Å): "
|
|
224
|
+
"normal modes left in the standard orientation", rmsd)
|
|
225
|
+
return normal_modes
|
|
226
|
+
n_atoms = std.shape[0]
|
|
227
|
+
disp = normal_modes.T.reshape(-1, n_atoms, 3) @ R
|
|
228
|
+
return np.ascontiguousarray(disp.reshape(-1, 3 * n_atoms).T)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ensemble-analyzer
|
|
3
|
-
Version: 1.2
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: Automatic Refinement of Conformational Ensemble
|
|
5
5
|
Author-email: Andrea Pellegrini <andrea.pellegrini15@unibo.it>, Paolo Righi <paolo.righi@unibo.it>, Andrea Mazzanti <andrea.mazzanti@unibo.it>, Michele Mancinelli <michele.mancinelli@unibo.it>
|
|
6
6
|
Maintainer-email: Andrea Pellegrini <andrea.pellegrini15@unibo.it>, Paolo Righi <paolo.righi@unibo.it>
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer.egg-info/SOURCES.txt
RENAMED
|
@@ -97,6 +97,7 @@ src/ensemble_analyzer/parsers/base.py
|
|
|
97
97
|
src/ensemble_analyzer/parsers/gaussian.py
|
|
98
98
|
src/ensemble_analyzer/parsers/nwchem.py
|
|
99
99
|
src/ensemble_analyzer/parsers/orca.py
|
|
100
|
+
src/ensemble_analyzer/parsers/vibrations.py
|
|
100
101
|
src/ensemble_analyzer/protocol/__init__.py
|
|
101
102
|
src/ensemble_analyzer/protocol/protocol.py
|
|
102
103
|
src/ensemble_analyzer/protocol/solvent.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_clustering/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_logger/create_log.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_logger/formatter.py
RENAMED
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_managers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_managers/prism_backend.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_managers/pruning_manager.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_parser_arguments.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_parser_parameter.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_spectral/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_spectral/comp_electronic.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_spectral/comp_vibronic.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_spectral/compare.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_spectral/experimental.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/_spectral/graph_default.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/__init__.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/_ml_base.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/aimnet.py
RENAMED
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/fairchem.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/gaussian.py
RENAMED
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/nwchem.py
RENAMED
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/skala_calc.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/calculators/tblite.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/get_av_energy.py
RENAMED
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/pickle_editor/cli.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/pickle_editor/core.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/pickle_editor/tui.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/cli/protocol_wizard/main.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/conformer/__init__.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/conformer/conformer.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/conformer/energy_data.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/conformer/spectral_data.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/parameters_file/basis_sets
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/parameters_file/functionals
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/protocol/__init__.py
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer/protocol/protocol.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer.egg-info/requires.txt
RENAMED
|
File without changes
|
{ensemble_analyzer-1.2 → ensemble_analyzer-1.2.1}/src/ensemble_analyzer.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|