firecode 1.0.0__py3-none-any.whl

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 (59) hide show
  1. firecode/TEST_NOTEBOOK.ipynb +3940 -0
  2. firecode/__init__.py +0 -0
  3. firecode/__main__.py +118 -0
  4. firecode/_gaussian.py +97 -0
  5. firecode/algebra.py +405 -0
  6. firecode/ase_manipulations.py +879 -0
  7. firecode/atropisomer_module.py +516 -0
  8. firecode/automep.py +130 -0
  9. firecode/calculators/__init__.py +29 -0
  10. firecode/calculators/_gaussian.py +98 -0
  11. firecode/calculators/_mopac.py +242 -0
  12. firecode/calculators/_openbabel.py +154 -0
  13. firecode/calculators/_orca.py +129 -0
  14. firecode/calculators/_xtb.py +786 -0
  15. firecode/concurrent_test.py +119 -0
  16. firecode/embedder.py +2590 -0
  17. firecode/embedder_options.py +577 -0
  18. firecode/embeds.py +881 -0
  19. firecode/errors.py +65 -0
  20. firecode/graph_manipulations.py +333 -0
  21. firecode/hypermolecule_class.py +364 -0
  22. firecode/mep_relaxer.py +199 -0
  23. firecode/modify_settings.py +186 -0
  24. firecode/mprof.py +65 -0
  25. firecode/multiembed.py +148 -0
  26. firecode/nci.py +186 -0
  27. firecode/numba_functions.py +260 -0
  28. firecode/operators.py +776 -0
  29. firecode/optimization_methods.py +609 -0
  30. firecode/parameters.py +84 -0
  31. firecode/pka.py +275 -0
  32. firecode/profiler.py +17 -0
  33. firecode/pruning.py +421 -0
  34. firecode/pt.py +32 -0
  35. firecode/quotes.json +6651 -0
  36. firecode/quotes.py +9 -0
  37. firecode/reactive_atoms_classes.py +666 -0
  38. firecode/references.py +11 -0
  39. firecode/rmsd.py +74 -0
  40. firecode/settings.py +75 -0
  41. firecode/solvents.py +126 -0
  42. firecode/tests/C2F2H4.xyz +10 -0
  43. firecode/tests/C2H4.xyz +8 -0
  44. firecode/tests/CH3Cl.xyz +7 -0
  45. firecode/tests/HCOOH.xyz +7 -0
  46. firecode/tests/HCOOOH.xyz +8 -0
  47. firecode/tests/chelotropic.txt +3 -0
  48. firecode/tests/cyclical.txt +3 -0
  49. firecode/tests/dihedral.txt +2 -0
  50. firecode/tests/string.txt +3 -0
  51. firecode/tests/trimolecular.txt +9 -0
  52. firecode/tests.py +151 -0
  53. firecode/torsion_module.py +1035 -0
  54. firecode/utils.py +541 -0
  55. firecode-1.0.0.dist-info/LICENSE +165 -0
  56. firecode-1.0.0.dist-info/METADATA +321 -0
  57. firecode-1.0.0.dist-info/RECORD +59 -0
  58. firecode-1.0.0.dist-info/WHEEL +5 -0
  59. firecode-1.0.0.dist-info/top_level.txt +1 -0
firecode/rmsd.py ADDED
@@ -0,0 +1,74 @@
1
+ import numba as nb
2
+ import numpy as np
3
+
4
+ from firecode.algebra import get_alignment_matrix, norm_of
5
+
6
+
7
+ @nb.njit
8
+ def np_mean_along_axis(axis, arr):
9
+ '''
10
+ Workaround to specify axis parameters to
11
+ numba functions, adapted from
12
+ https://github.com/numba/numba/issues/1269
13
+
14
+ '''
15
+ assert arr.ndim == 2
16
+ assert axis in [0, 1]
17
+ if axis == 0:
18
+ result = np.empty(arr.shape[1], dtype=np.float64)
19
+ for i in range(len(result)):
20
+ result[i] = np.mean(arr[:, i])
21
+ else:
22
+ result = np.empty(arr.shape[0], dtype=np.float64)
23
+ for i in range(len(result)):
24
+ result[i] = np.mean(arr[i, :])
25
+ return result
26
+
27
+ @nb.njit
28
+ def rmsd_and_max_numba(p, q, center=False):
29
+ '''
30
+ Returns a tuple with the RMSD between p and q
31
+ and the maximum deviation of their positions
32
+
33
+ '''
34
+
35
+ if center:
36
+ # p -= p.mean(axis=0)
37
+ # q -= q.mean(axis=0)
38
+ p -= np_mean_along_axis(0, p)
39
+ q -= np_mean_along_axis(0, q)
40
+
41
+ # get alignment matrix
42
+ rot_mat = get_alignment_matrix(p, q)
43
+
44
+ # Apply it to p
45
+ p = np.ascontiguousarray(p) @ rot_mat
46
+
47
+ # Calculate deviations
48
+ diff = p - q
49
+
50
+ # Calculate RMSD
51
+ rmsd = np.sqrt((diff * diff).sum() / len(diff))
52
+
53
+ # # Calculate max deviation
54
+ # max_delta = np.linalg.norm(diff, axis=1).max()
55
+ max_delta = max([norm_of(v) for v in diff])
56
+
57
+ return rmsd, max_delta
58
+
59
+ def _rmsd_similarity(ref, structures, rmsd_thr=0.5) -> bool:
60
+ '''
61
+ Simple, RMSD similarity eval function.
62
+
63
+ '''
64
+
65
+ # iterate over target structures
66
+ for structure in structures:
67
+
68
+ # compute RMSD and max deviation
69
+ rmsd_value, maxdev_value = rmsd_and_max_numba(ref, structure)
70
+
71
+ if rmsd_value < rmsd_thr and maxdev_value < 2 * rmsd_thr:
72
+ return True
73
+
74
+ return False
firecode/settings.py ADDED
@@ -0,0 +1,75 @@
1
+ # coding=utf-8
2
+ '''
3
+ FIRECODE: Filtering Refiner and Embedder for Conformationally Dense Ensembles
4
+ Copyright (C) 2021-2024 Nicolò Tampellini
5
+
6
+ SPDX-License-Identifier: LGPL-3.0-or-later
7
+
8
+ This program is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU Lesser General Public License as published by
10
+ the Free Software Foundation, either version 3 of the License, or
11
+ (at your option) any later version.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU Lesser General Public License for more details.
17
+
18
+ You should have received a copy of the GNU Lesser General Public License
19
+ along with this program. If not, see
20
+ https://www.gnu.org/licenses/lgpl-3.0.en.html#license-text.
21
+
22
+ '''
23
+
24
+ # IF YOU MANUALLY EDIT THIS FILE, BE SURE NOT TO
25
+ # CHANGE IDENTATION/WHITESPACES/NEWLINES!
26
+
27
+ FF_OPT_BOOL = True
28
+ # Whether to run Force Field optimization
29
+ # prior to the final one.
30
+
31
+ FF_CALC = 'XTB'
32
+ # Calculator to perform Force Field optimizations.
33
+ # Possibilites are:
34
+ # 'GAUSSIAN' : FF methods supported by Gaussian (UFF, MMFF)
35
+ # 'XTB' : GFN-FF method
36
+
37
+ DEFAULT_FF_LEVELS = {
38
+ ### DO NOT REMOVE
39
+ ### THESE TWO LINES
40
+ 'GAUSSIAN':'UFF',
41
+ 'XTB':'GFN-FF',
42
+ }
43
+ # Default levels used to run calculations, overridden by FFLEVEL keyword
44
+
45
+ CALCULATOR = 'XTB'
46
+ # Calculator used to run geometry optimization.
47
+ # Possibilites are:
48
+ # 'MOPAC' : Semiempirical MOPAC2016 (PM7, PM6-DH3, ...)
49
+ # 'ORCA' : All methods supported by ORCA
50
+ # 'GAUSSIAN' : All methods supported by Gaussian
51
+ # 'XTB' : All methods supported by XTB
52
+ # 'AIMNET2' : wB97M-D3
53
+
54
+ DEFAULT_LEVELS = {
55
+ 'MOPAC':'PM7',
56
+ 'ORCA':'PM3',
57
+ 'GAUSSIAN':'PM6',
58
+ 'XTB':'GFN2-xTB',
59
+ 'AIMNET2':'wB97M-D3',
60
+ }
61
+ # Default levels used to run calculations, overridden by LEVEL keyword
62
+
63
+ COMMANDS = {
64
+ 'MOPAC':'MOPAC2016.exe',
65
+ 'ORCA':'/vast/palmer/apps/avx.grace/software/ORCA/5.0.4-gompi-2020b/bin/orca',
66
+ 'GAUSSIAN':'g09.exe',
67
+ 'XTB':'xtb',
68
+ }
69
+ # Command with which calculators will be called from the command line
70
+
71
+ PROCS = 0
72
+ # Number of processors (cores) per job to be used by XTB, ORCA and/or Gaussian (0 is auto)
73
+
74
+ MEM_GB = 8
75
+ # Memory allocated for each job (Gaussian/ORCA)
firecode/solvents.py ADDED
@@ -0,0 +1,126 @@
1
+ # coding=utf-8
2
+ '''
3
+ FIRECODE: Filtering Refiner and Embedder for Conformationally Dense Ensembles
4
+ Copyright (C) 2021-2024 Nicolò Tampellini
5
+
6
+ SPDX-License-Identifier: LGPL-3.0-or-later
7
+
8
+ This program is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU Lesser General Public License as published by
10
+ the Free Software Foundation, either version 3 of the License, or
11
+ (at your option) any later version.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU Lesser General Public License for more details.
17
+
18
+ You should have received a copy of the GNU Lesser General Public License
19
+ along with this program. If not, see
20
+ https://www.gnu.org/licenses/lgpl-3.0.en.html#license-text.
21
+
22
+ '''
23
+
24
+ import sys
25
+
26
+ xtb_solvents = [
27
+ 'acetone',
28
+ 'acetonitrile',
29
+ 'aniline',
30
+ 'benzaldehyde',
31
+ 'benzene',
32
+ 'ch2cl2',
33
+ 'chcl3',
34
+ 'cs2',
35
+ 'dioxane',
36
+ 'dmf',
37
+ 'dmso',
38
+ 'ether',
39
+ 'ethylacetate',
40
+ 'furane',
41
+ 'hexadecane',
42
+ 'hexane',
43
+ 'methanol',
44
+ 'nitromethane',
45
+ 'octanol',
46
+ 'octanolwet',
47
+ 'phenol',
48
+ 'toluene',
49
+ 'thf',
50
+ 'water',
51
+
52
+ 'none', # This is required for the ASE get_calc function
53
+ ]
54
+
55
+ xtb_solvents = xtb_solvents + ['' for _ in range(3-len(xtb_solvents)%3)]
56
+ gap = 18
57
+ xtb_supported = ''.join([(f'{xtb_solvents[i]}{" "*(gap-len(xtb_solvents[i]))}'
58
+ f'{xtb_solvents[i+1]}{" "*(gap-len(xtb_solvents[i+1]))}'
59
+ f'{xtb_solvents[i+2]}\n')
60
+ for i, _ in enumerate(xtb_solvents) if i%3==0])
61
+
62
+ epsilon_dict = {
63
+ 'aceticacid':6.15,
64
+ 'acetone':20.7,
65
+ 'acetonitrile':37.5,
66
+ 'aniline':7.06,
67
+ 'benzaldehyde':17.9,
68
+ 'benzene':2.28,
69
+ 'chloroform':4.8,
70
+ 'cs2':2.63,
71
+ 'ch2cl2':8.93,
72
+ 'dioxane':2.25,
73
+ 'dmf':36.71,
74
+ 'dmso':46.68,
75
+ 'et2o':4.27,
76
+ 'dimethylether':6.18,
77
+ 'ethanol':24.3,
78
+ 'methanol':32.63,
79
+ 'ethylacetate':6.02,
80
+ 'furan':2.94,
81
+ 'hexadecane':2.05,
82
+ 'octanol':10.30,
83
+ 'phenol':12.4,
84
+ 'toluene':2.38,
85
+ 'thf':7.58,
86
+ 'water':80.1,
87
+ }
88
+
89
+ solvent_synonyms = {
90
+ 'ch3cooh':'aceticacid',
91
+ 'ch3cn':'acetonitrile',
92
+ 'ch3cl':'chloroform',
93
+ 'dcm':'ch2cl2',
94
+ 'dichloromethane':'ch2cl2',
95
+ 'carbondisuphide':'cs2',
96
+ 'carbondisulfide':'cs2',
97
+ 'diethylether':'et2o',
98
+ 'etoh':'ethanol',
99
+ 'ch3oh':'methanol',
100
+ 'meoh':'methanol',
101
+ 'h2o':'water',
102
+ }
103
+
104
+ new_theory_level = {
105
+ 'MOPAC':lambda theory_level, solvent: f'EPS={epsilon_dict[solvent]}',
106
+ 'GAUSSIAN':lambda theory_level, solvent: f'scrf=(cpcm,solvent={solvent})',
107
+ 'ORCA':lambda theory_level, solvent: f'! CPCM\n%cpcm\nepsilon {epsilon_dict[solvent]}\nend',
108
+ # 'XTB':lambda theory_level, _: '',
109
+ }
110
+
111
+ def get_solvent_line(solvent, calculator, theory_level):
112
+
113
+ if solvent is None:
114
+ return ''
115
+
116
+ if solvent in solvent_synonyms:
117
+ solvent = solvent_synonyms[solvent]
118
+
119
+ if solvent not in epsilon_dict:
120
+ print(f'Solvent \'{solvent}\' not recognized. Implemented solvents are:')
121
+ for s in epsilon_dict:
122
+ print(' '+s)
123
+ print('Please note that not all solvents will work with all calculators.')
124
+ sys.exit()
125
+
126
+ return new_theory_level[calculator](theory_level, solvent)
@@ -0,0 +1,10 @@
1
+ 8
2
+ Energy: 0.3670310
3
+ C -1.18817 -0.16528 -0.05121
4
+ C 0.33126 -0.22526 -0.05522
5
+ H -1.52420 0.87833 0.12518
6
+ F -1.68941 -0.98039 0.94728
7
+ H -1.57901 -0.50941 -1.03192
8
+ F 0.82329 0.20835 1.16236
9
+ H 0.72954 0.42644 -0.86122
10
+ H 0.66732 -1.26825 -0.23524
@@ -0,0 +1,8 @@
1
+ 6
2
+ Title
3
+ C -1.08800 -0.88350 -0.00000
4
+ H -0.55280 -1.81000 -0.00000
5
+ H -2.15800 -0.88370 0.00000
6
+ C -0.41070 0.29030 0.00000
7
+ H -0.94590 1.21690 -0.00000
8
+ H 0.65930 0.29060 0.00000
@@ -0,0 +1,7 @@
1
+ 5
2
+ Title
3
+ C 3.04350 0.27540 0.00000
4
+ H 3.40010 -0.73340 0.00000
5
+ H 3.40020 0.77980 -0.87370
6
+ H 1.97350 0.27540 0.00000
7
+ Cl 3.63020 1.10500 1.43700
@@ -0,0 +1,7 @@
1
+ 5
2
+ Title
3
+ C 0.49280 -0.05800 0.00000
4
+ O 0.84090 -0.61220 1.03830
5
+ H 0.74900 -0.46260 -1.00190
6
+ O -0.26980 1.15180 0.00000
7
+ H -0.44140 1.42240 0.90490
@@ -0,0 +1,8 @@
1
+ 6
2
+ HCOOOH.out Energy: -59.7233800
3
+ C 0.53505 -0.19559 -0.07404
4
+ O 0.68928 -0.94130 0.86030
5
+ H 0.84623 -0.32774 -1.11185
6
+ O -0.08470 1.00585 0.03772
7
+ O -0.53234 1.31557 1.35825
8
+ H -0.24162 0.53875 1.91661
@@ -0,0 +1,3 @@
1
+ DIST(A=2.5,B=2.5) SADDLE
2
+ C2H4.xyz 0A 3B
3
+ HCOOOH.xyz 4AB
@@ -0,0 +1,3 @@
1
+ DIST(A=2.2,B=2.3) BYPASS
2
+ C2H4.xyz 0A 3B
3
+ C2H4.xyz 0B 3A
@@ -0,0 +1,2 @@
1
+ KCAL=0
2
+ scan> C2F2H4.xyz 3 0 1 5
@@ -0,0 +1,3 @@
1
+ SOLVENT=methanol DIST(A=2.5)
2
+ CH3Cl.xyz 0A
3
+ HCOOH.xyz 3A
@@ -0,0 +1,9 @@
1
+ DIST(A=2.5,x=2,y=2.5,C=1) SHRINK NCI ROTRANGE=10 STEPS=1
2
+ CH3Cl.xyz 0A 4y
3
+ HCOOH.xyz 1A 4x 0C 2C
4
+ HCOOH.xyz 1x 4y
5
+
6
+ # Trimolecular SN2
7
+ # A is O-Cl reacting pair
8
+ # x is the intra-acid hydrogen bond
9
+ # y is the H-Cl hydrogen bond
firecode/tests.py ADDED
@@ -0,0 +1,151 @@
1
+ # coding=utf-8
2
+ '''
3
+ FIRECODE: Filtering Refiner and Embedder for Conformationally Dense Ensembles
4
+ Copyright (C) 2021-2024 Nicolò Tampellini
5
+
6
+ SPDX-License-Identifier: LGPL-3.0-or-later
7
+
8
+ This program is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU Lesser General Public License as published by
10
+ the Free Software Foundation, either version 3 of the License, or
11
+ (at your option) any later version.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU Lesser General Public License for more details.
17
+
18
+ You should have received a copy of the GNU Lesser General Public License
19
+ along with this program. If not, see
20
+ https://www.gnu.org/licenses/lgpl-3.0.en.html#license-text.
21
+
22
+ '''
23
+
24
+ import sys
25
+
26
+ def run_tests():
27
+
28
+ import os
29
+ import time
30
+ from subprocess import CalledProcessError
31
+
32
+ os.chdir(os.path.dirname(os.path.realpath(__file__)))
33
+
34
+ from firecode.settings import (CALCULATOR, COMMANDS, DEFAULT_FF_LEVELS,
35
+ DEFAULT_LEVELS, FF_CALC, FF_OPT_BOOL, PROCS)
36
+
37
+ if CALCULATOR not in ('MOPAC','ORCA','GAUSSIAN','XTB'):
38
+ raise Exception(f'{CALCULATOR} is not a valid calculator. Use MOPAC, ORCA, GAUSSIAN or XTB.')
39
+
40
+ import numpy as np
41
+ from ase.atoms import Atoms
42
+ from ase.optimize import LBFGS
43
+
44
+ from firecode.ase_manipulations import get_ase_calc
45
+ from firecode.optimization_methods import Opt_func_dispatcher
46
+ from firecode.utils import (HiddenPrints, clean_directory, loadbar, read_xyz,
47
+ run_command, time_to_string)
48
+
49
+ os.chdir('tests')
50
+
51
+ t_start_run = time.perf_counter()
52
+
53
+ data = read_xyz('C2H4.xyz')
54
+
55
+ dispatcher = Opt_func_dispatcher()
56
+
57
+ if CALCULATOR == 'AIMNET2':
58
+ dispatcher.load_aimnet2_calc(DEFAULT_LEVELS[CALCULATOR])
59
+
60
+ ##########################################################################
61
+
62
+ print('\nRunning tests for FIRECODE. Settings used:')
63
+ print(f'{CALCULATOR=}')
64
+
65
+ if CALCULATOR != 'XTB':
66
+ print(f'{CALCULATOR} COMMAND = {COMMANDS[CALCULATOR]}')
67
+
68
+ print('\nTesting calculator...')
69
+
70
+ ##########################################################################
71
+
72
+ dispatcher.opt_funcs_dict[CALCULATOR](data.atomcoords[0],
73
+ data.atomnos,
74
+ method=DEFAULT_LEVELS[CALCULATOR],
75
+ procs=PROCS,
76
+ read_output=False)
77
+
78
+ print(f'{CALCULATOR} raw calculator works.')
79
+
80
+ ##########################################################################
81
+
82
+ atoms = Atoms('HH', positions=np.array([[0, 0, 0], [0, 0, 1]]))
83
+ atoms.calc = get_ase_calc((CALCULATOR, DEFAULT_LEVELS[CALCULATOR], PROCS, None))
84
+ LBFGS(atoms, logfile=None).run()
85
+
86
+ clean_directory()
87
+ print(f'{CALCULATOR} ASE calculator works.')
88
+
89
+ ##########################################################################
90
+
91
+ print(f'\n{FF_OPT_BOOL=}')
92
+ ff = f'on. Calculator is {FF_CALC}. Checking its status.' if FF_OPT_BOOL else 'off.'
93
+ print(f'Force Field optimization is turned {ff}')
94
+
95
+ if FF_OPT_BOOL:
96
+ if FF_CALC != 'OB': # 'XTB', 'GAUSSIAN'
97
+ dispatcher.opt_funcs_dict[FF_CALC](data.atomcoords[0],
98
+ data.atomnos,
99
+ method=DEFAULT_FF_LEVELS[FF_CALC],
100
+ procs=PROCS,
101
+ read_output=False)
102
+
103
+ print(f'{FF_CALC} FF raw calculator works.')
104
+
105
+ ##########################################################################
106
+
107
+ if FF_CALC != 'OB':
108
+ atoms.calc = get_ase_calc((FF_CALC, DEFAULT_FF_LEVELS[FF_CALC], PROCS, None))
109
+ LBFGS(atoms, logfile=None).run()
110
+
111
+ clean_directory()
112
+ print(f'{FF_CALC} ASE calculator works.')
113
+
114
+ print('\nNo installation faults detected with the current settings. Running tests.')
115
+
116
+ ##########################################################################
117
+
118
+ tests = []
119
+ for f in os.listdir():
120
+ if f.endswith('.txt'):
121
+ tests.append(os.path.realpath(f))
122
+
123
+ # os.chdir(os.path.dirname(os.getcwd()))
124
+ # os.chdir('firecode')
125
+ # # Back to ./firecode
126
+
127
+ times = []
128
+ for i, f in enumerate(tests):
129
+ name = f.split('\\')[-1].split('/')[-1][:-4] # trying to make it work for either Win, Linux (and Mac?)
130
+ loadbar(i, len(tests), f'Running firecode tests ({name}): ')
131
+
132
+ t_start = time.perf_counter()
133
+ try:
134
+ with HiddenPrints():
135
+ run_command(f'python -m firecode {f} -n {name}')
136
+
137
+ except CalledProcessError as error:
138
+ print('\n\n--> An error occurred:\n')
139
+ print(error.stderr.decode("utf-8"))
140
+ sys.exit()
141
+
142
+ t_end = time.perf_counter()
143
+ times.append(t_end-t_start)
144
+
145
+ loadbar(len(tests), len(tests), f'Running firecode tests ({name}): ')
146
+
147
+ print()
148
+ for i, f in enumerate(tests):
149
+ print(' {:25s}{} s'.format(f.split('\\')[-1].split('/')[-1][:-4], round(times[i], 3)))
150
+
151
+ print(f'\nfirecode tests completed with no errors. ({time_to_string(time.perf_counter() - t_start_run)})\n')