Skip to content

Commit 0cd84e8

Browse files
authored
Merge pull request #3 from ccdc-opensource/utility_scripts
Added Utility scripts and changed formatting
2 parents 0865ab9 + 0fb4e2d commit 0cd84e8

File tree

18 files changed

+382
-43
lines changed

18 files changed

+382
-43
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55

66
A repository containing scripts that have been created to leverage the toolkit found within
77
the [CCDC portfolio](https://www.ccdc.cam.ac.uk/solutions/) that are accessible via
8-
the [CSD-Python API ](https://www.ccdc.cam.ac.uk/solutions/csd-core/components/csd-python-api/).
8+
the [CSD Python API](https://www.ccdc.cam.ac.uk/solutions/csd-core/components/csd-python-api/).
99

1010
The purpose of this platform is to distribute knowledge and allow for scientific collaborations. Scripts are provided on an as-is basis and while their use is not supported we do welcome feedback on potential improvements. All scripts are tested against the latest version of the CSD Python API as installed with the CSD Portfolio.
1111

12-
> For feedback or to report any issues please contact [support@ccdc.cam.ac.uk](support@ccdc.cam.ac.uk)
12+
> For feedback or to report any issues please contact [support@ccdc.cam.ac.uk](mailto:support@ccdc.cam.ac.uk)
1313
1414
## Content
1515

scripts/concat_mol2/ReadMe.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Concat Mol2
2+
3+
## Summary
4+
5+
Opens a set of mol2 files in the working directory and creates one concatenated multi-mol2 file.
6+
Optionally delete the individual mol2 files other than the new concat.mol2
7+
8+
## Requirements
9+
10+
- CSD Python API not required.
11+
- Mol2 files must be in the same directory.
12+
13+
## Licensing Requirements
14+
15+
No license required.
16+
17+
## Instructions on running
18+
19+
```cmd
20+
> python concat_mol2.py
21+
```
22+
23+
Help output:
24+
```cmd
25+
python concat_mol2.py -h
26+
usage: concat_mol2.py [-h] [-d]
27+
28+
optional arguments:
29+
-h, --help show this help message and exit
30+
-d, --delete_contributors
31+
Remove contributing individual mol2 files after
32+
concatenation
33+
```
34+
35+
## Author
36+
37+
_Peter Galek_ (2014)
38+
39+
> For feedback or to report any issues please contact [support@ccdc.cam.ac.uk](mailto:support@ccdc.cam.ac.uk)

scripts/concat_mol2/concat_mol2.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#
2+
# This script can be used for any purpose without limitation subject to the
3+
# conditions at http://www.ccdc.cam.ac.uk/Community/Pages/Licences/v2.aspx
4+
#
5+
# This permission notice and the following statement of attribution must be
6+
# included in all copies or substantial portions of this script.
7+
#
8+
# 2014-08-11: created by Peter Galek, The Cambridge Crystallographic Data Centre
9+
# 2022-02-24: updated by Alex Moldovan, The Cambridge Crystallographic Data Centre
10+
#
11+
12+
import glob
13+
import argparse
14+
import os
15+
16+
17+
def main(delete_separate_files):
18+
mol2_files = glob.glob('*.mol2')
19+
count = 0
20+
with open('concat.mol2', 'w') as outfile:
21+
for f in mol2_files:
22+
if f == 'concat.mol2':
23+
continue
24+
with open(f, 'r') as infile:
25+
outfile.write(infile.read())
26+
count += 1
27+
print(f"{count} files concatenated.")
28+
29+
if delete_separate_files == True:
30+
count = 0
31+
for f in mol2_files:
32+
if f == 'concat.mol2':
33+
continue
34+
os.remove(f)
35+
count += 1
36+
print(f"{count} files removed.")
37+
38+
39+
if __name__ == '__main__':
40+
parser = argparse.ArgumentParser(description=__doc__)
41+
parser.add_argument('-d', '--delete_contributors', action='store_true',
42+
help='Remove contributing individual mol2 files after concatenation')
43+
44+
args = parser.parse_args()
45+
main(args.delete_contributors)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Create CASTEP Input
2+
3+
## Summary
4+
5+
Allows the user to generate a set of CASTEP input files (.cell and .params) for a structure viewed in Mercury.
6+
7+
![img.png](assets/file_output.png)
8+
9+
## Requirements
10+
11+
Tested with CSD Python API 3.0.9
12+
13+
Requires user to add script to Mercury interface.
14+
15+
## Licensing Requirements
16+
17+
- CSD-Core
18+
19+
If you wish to run CASTEP, you will need to acquire a licence for CASTEP, this is not supplied by the CCDC.
20+
21+
## Instructions on running
22+
23+
Add script with Folder to Mercury interface (Mercury -> CSD Python API-> Options -> Add Location)
24+
25+
![img.png](assets/add_script_location.png)
26+
27+
Select refcode of interest or load structure into Mercury.
28+
29+
Select script from CSD Python API dropdown.
30+
31+
![img.png](assets/select_script.png)
32+
33+
## Author
34+
35+
_Anthony Reilly_ (2016)
36+
37+
> For feedback or to report any issues please contact [support@ccdc.cam.ac.uk](mailto:support@ccdc.cam.ac.uk)
4.52 KB
Loading
4.28 KB
Loading
5.36 KB
Loading
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#
2+
# This script can be used for any purpose without limitation subject to the
3+
# conditions at http://www.ccdc.cam.ac.uk/Community/Pages/Licences/v2.aspx
4+
#
5+
# This permission notice and the following statement of attribution must be
6+
# included in all copies or substantial portions of this script.
7+
#
8+
# 2016-12-06 - created by Anthony Reilly, The Cambridge Crystallographic Data Centre based on code from Andrew Maloney, CCDC
9+
# 2021-02-24 - updated by Alex Moldovan, The Cambridge Crystallographic Data Centre
10+
#
11+
12+
import os
13+
from ccdc.utilities import ApplicationInterface
14+
15+
16+
def make_castep_input(crystal, kp_spacing=0.06, cut_off=750.000, task='SinglePoint', di_opt=False):
17+
# cell file
18+
with open('%s.cell' % crystal.identifier, 'w') as cell_file:
19+
cell_file.write('%BLOCK LATTICE_ABC\n')
20+
cell_file.write(' %11.7f %11.7f %11.7f\n' % crystal.cell_lengths)
21+
cell_file.write(' %11.7f %11.7f %11.7f\n' % crystal.cell_angles)
22+
cell_file.write('%ENDBLOCK LATTICE_ABC\n\n')
23+
cell_file.write('%BLOCK POSITIONS_FRAC\n')
24+
for op in crystal.symmetry_operators:
25+
mol = crystal.symmetric_molecule(op, [0, 0, 0], force=False)
26+
for atom in mol.atoms:
27+
cell_file.write(' %s %19.16f %19.16f %19.16f\n' % (atom.atomic_symbol,
28+
atom.fractional_coordinates.x,
29+
atom.fractional_coordinates.y,
30+
atom.fractional_coordinates.z))
31+
cell_file.write('%ENDBLOCK POSITIONS_FRAC\n\n')
32+
33+
cell_file.write('KPOINT_MP_SPACING ' + str(kp_spacing) + '\n\n')
34+
35+
cell_file.write('%BLOCK SYMMETRY_OPS\n')
36+
for op in crystal.symmetry_operators:
37+
rotation = crystal.symmetry_rotation(op)
38+
trans = crystal.symmetry_translation(op)
39+
cell_file.write(' %18.15f %18.15f %18.15f\n' % (rotation[0], rotation[1], rotation[2]))
40+
cell_file.write(' %18.15f %18.15f %18.15f\n' % (rotation[3], rotation[4], rotation[5]))
41+
cell_file.write(' %18.15f %18.15f %18.15f\n' % (rotation[6], rotation[7], rotation[8]))
42+
cell_file.write(' %18.15f %18.15f %18.15f\n' % (trans[0], trans[1], trans[2]))
43+
cell_file.write('###\n')
44+
cell_file.write('%ENDBLOCK SYMMETRY_OPS\n\n')
45+
46+
# param file
47+
with open('%s.param' % crystal.identifier, 'w') as param_file:
48+
param_file.write('task : ' + task + '\n')
49+
param_file.write('comment : CASTEP calculation for %s\n' % crystal.identifier)
50+
51+
param_file.write('xc_functional : PBE\n')
52+
param_file.write('sedc_scheme : TS\n')
53+
54+
param_file.write('metals_method : dm\n')
55+
param_file.write('mixing_scheme : Pulay\n')
56+
param_file.write('spin_polarized : false\n')
57+
param_file.write('opt_strategy : speed\n')
58+
param_file.write('cut_off_energy : ' + str(cut_off) + '\n')
59+
param_file.write('grid_scale : 2.0\n')
60+
param_file.write('fine_grid_scale : 3.0\n')
61+
param_file.write('elec_energy_tol : 1.000e-008\n')
62+
param_file.write('fix_occupancy : true\n')
63+
if task != 'SinglePoint':
64+
param_file.write('finite_basis_corr : 2\n')
65+
66+
param_file.write('geom_modulus_est : 50 GPa\n')
67+
param_file.write('geom_max_iter : 200\n')
68+
param_file.write('num_backup_iter : 1\n')
69+
70+
param_file.write('geom_energy_tol : 5E-06\n')
71+
param_file.write('geom_stress_tol : 0.02\n')
72+
param_file.write('geom_disp_tol : 1E-03\n')
73+
param_file.write('geom_force_tol : 5E-03\n')
74+
if di_opt:
75+
param_file.write('geom_method : delocalised \n')
76+
77+
param_file.write('write_cif_structure : true\n')
78+
param_file.write('write_cell_structure : true\n')
79+
param_file.write('#continuation : default\n')
80+
81+
return True
82+
83+
84+
if __name__ == '__main__':
85+
helper = ApplicationInterface()
86+
entry = helper.current_entry
87+
crystal = entry.crystal
88+
os.chdir(helper.output_directory_path)
89+
make_castep_input(crystal)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Create Gaussian Input
2+
3+
## Summary
4+
5+
Allows the user to generate a Gaussian input file (.gjf) for a given CSD refcode or .mol2. If you wish to run different keywords the script will need to be changed manually.
6+
7+
8+
## Requirements
9+
10+
Tested with CSD Python API 3.0.9
11+
12+
13+
## Licensing Requirements
14+
15+
CSD-Core
16+
17+
If you wish to run Gaussian, you will need to acquire a licence for Gaussian, this is not supplied by the CCDC.
18+
19+
## Instructions on running
20+
21+
To create an input file for the
22+
```cmd
23+
>python create_gaussian_input.py HXACAN
24+
```
25+
26+
```cmd
27+
>python create_gaussian_input.py HXACAN.mol2
28+
```
29+
30+
## Author
31+
32+
_Andrew Maloney_(2015)
33+
34+
> For feedback or to report any issues please contact [support@ccdc.cam.ac.uk](mailto:support@ccdc.cam.ac.uk)
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#
2+
# This script can be used for any purpose without limitation subject to the
3+
# conditions at http://www.ccdc.cam.ac.uk/Community/Pages/Licences/v2.aspx
4+
#
5+
# This permission notice and the following statement of attribution must be
6+
# included in all copies or substantial portions of this script.
7+
#
8+
# 2015-06-17: created by Andrew Maloney the Cambridge Crystallographic Data Centre
9+
#
10+
11+
from __future__ import division, absolute_import, print_function
12+
13+
"""
14+
This script will generate a generic Gaussian input file
15+
Input: CSD Identifier as a string or .mol2
16+
Output: GJF input file
17+
"""
18+
19+
import sys
20+
import os
21+
import ccdc.io
22+
23+
24+
def fatal(*args):
25+
"""Generates an error message if necessary to smoothly exit the program."""
26+
print('ERROR:', ' '.join(map(str, args)))
27+
sys.exit(1)
28+
29+
30+
def file_writer(molecule, name):
31+
"""Writes a standard Gaussian input file for all molecules contained in the structure files."""
32+
if not mol.all_atoms_have_sites:
33+
fatal(entry_id, 'has some atoms without coordinates')
34+
mol.normalise_hydrogens()
35+
36+
for i, component in enumerate(molecule.components):
37+
38+
file_name = '%s_molecule%d.gjf' % (name, i)
39+
f = open(file_name, 'w')
40+
41+
f.write('#B3LYP/6-31G** opt\n')
42+
f.write('\n')
43+
f.write('Standard Gaussian Input File for %s, molecule %d\n' % (name, i))
44+
f.write('\n')
45+
f.write('0 1\n')
46+
47+
for atom in component.atoms:
48+
f.write('%2s %9.6f %9.6f %9.6f\n' % (atom.atomic_symbol,
49+
atom.coordinates.x,
50+
atom.coordinates.y,
51+
atom.coordinates.z))
52+
53+
f.write('\n')
54+
f.write('--Link1--')
55+
f.write('\n')
56+
f.write('\n')
57+
f.write('\n')
58+
59+
f.close()
60+
61+
62+
if __name__ == '__main__':
63+
# Get the relevant structure typed by user
64+
if len(sys.argv) != 2:
65+
fatal('you must supply a structure identifier.')
66+
entry_id = sys.argv[1]
67+
68+
# Checking the current directory for user cif file
69+
filepath = '%s' % entry_id
70+
if os.path.isfile(filepath):
71+
reader = ccdc.io.MoleculeReader(filepath)
72+
for mol in reader:
73+
identifier = mol.identifier
74+
file_writer(mol, identifier)
75+
76+
else:
77+
# Read molecule from database
78+
reader = ccdc.io.MoleculeReader('CSD')
79+
identifier = entry_id
80+
try:
81+
mol = reader.molecule(entry_id)
82+
file_writer(mol, identifier)
83+
except RuntimeError:
84+
fatal(entry_id, '- structure not found')

0 commit comments

Comments
 (0)