Source code for schrodinger.application.desmond.system_builder_inp

#Name: System Builder Input Script
#Command: $SCHRODINGER/run system_builder_inp.py
"""
A script to create a system builder input file.

"""

#  System Builder Input Script
#  Developed by Byungchan Kim
#  April 2007,
#  Copyright Schrodinger, LLC.,
#  All rights reserved.

import os
import re
import sys

from schrodinger import structure
from schrodinger.application.desmond import smarts
from schrodinger.application.desmond.constants import CT_TYPE
from schrodinger.application.desmond.constants import NUM_COMPONENT
from schrodinger.infra import mm
from schrodinger.job import jobcontrol
from schrodinger.structutils.analyze import evaluate_asl

# Define water SMARTS patterns
water_smarts = ["[H]O[H]"]
zob_water_smarts = ["[H]O([H])_[*]", "[H]O[H]_[*]"]


[docs]class SystemBuilderInput: CHECK_SOLVENT_OVERLAP = 'check_solvent_overlap' CHECK_CRYSTAL_WATER_OVERLAP = 'check_crystal_water_overlap' YES, NO = 'Yes', 'No'
[docs] def __init__(self): self.reset()
[docs] def reset(self): self.vdw_scaling_factor = -1.0 self.oplsaa_version = '' self.solute_alignment_type = '' self.solute_alignment_value = 0 self.solute_fname = '' self.solute_st = [] self.membrane = 'DPPC.mae.gz' self.positive_ion = 'Na.mae' self.negative_ion = 'Cl.mae' self.salt_positive_ion = 'Na.mae' self.salt_negative_ion = 'Cl.mae' self.solvent = 'spc.box.mae' self.x_membrane_patch = 10.0 self.y_membrane_patch = 10.0 self.ion_type = 'positive' self.nion = 0 self.mmfepio_map_mode_option = -1 self.mmfepio_retain_angle_option = -1 self._ion_location = [] self._exclude_location = [] self._exclude_distance = 0.0 self.salt_concentration = 0.0 self.boundary_condition = 'cubic' self.a = 10.0 self.b = 10.0 self.c = 10.0 self.alpha = 90.0 self.beta = 90.0 self.gamma = 90.0 self._should_membranize = 0 self._should_solvate = 1 self._should_neutralize = 1 self._add_alchemical_ions = 0 self._use_alchemical_water = 0 self._remove_overlapped_crystal_water = 0 self._remove_overlapped_solvent = 1 self.use_buffer = 1 self.one_mae_file = '' self.mae_file = '' self.maeff_file = '' self.pdb_file = '' self.xyz_file = '' self.top_file = '' self.g96_file = ''
[docs] def setVdwScalingFactor(self, value=0): self.vdw_scaling_factor = value
[docs] def setOplsaaVersion(self, value=''): self.oplsaa_version = value
[docs] def setSoluteAlignment(self, name='', value=1): self.solute_alignment_type = name self.solute_alignment_value = value
[docs] def setMMFepioMapModeOption(self, value=1): self.mmfepio_map_mode_option = value
[docs] def setMMFepioRetainAngleOption(self, value=1): self.mmfepio_retain_angle_option = value
[docs] def setSolute(self, name): self.solute_fname = name
[docs] def fixSolute(self): name = self.solute_fname.lstrip('"').rstrip('"') st_reader = structure.StructureReader(name) full_system = -1 comp_st = [] for i, st in enumerate(st_reader): try: if st.property[CT_TYPE] == CT_TYPE.VAL.FULL_SYSTEM: full_system = i except: pass comp_st.append(st) if full_system >= 0: nfull_atom = comp_st[full_system].atom_total natom = 0 for i, st in enumerate(comp_st): if i != full_system: natom += st.atom_total if nfull_atom != natom: for st in comp_st: try: if st.property[CT_TYPE] == CT_TYPE.VAL.FULL_SYSTEM: del st.property[CT_TYPE] except: pass # remove alternate coordinates alternate_coord_names = [ "_pdb_alt_", "_m_alt_", "s_pdb_altloc_chars", ] for st in comp_st: for a in st.atom: for p in list(a.property): for alt in alternate_coord_names: if p.find(alt) >= 0: del a.property[p] self.solute_st = comp_st
[docs] def setPositiveIon(self, name='Na.mae'): self.positive_ion = name
[docs] def setNegativeIon(self, name='Cl.mae'): self.negative_ion = name
[docs] def setSaltPositiveIon(self, name='Na.mae'): self.salt_positive_ion = name
[docs] def setSaltNegativeIon(self, name='Cl.mae'): self.salt_negative_ion = name
[docs] def setMembrane(self, name='DPPC.mae.gz'): self.membrane = name
[docs] def setSolvent(self, name='spc.box.mae'): self.solvent = name
[docs] def setMembranize(self, value=1): self._should_membranize = value
[docs] def setMembranePatch(self, x_mem=10.0, y_mem=10.0): self.x_membrane_patch = x_mem self.y_membrane_patch = y_mem
[docs] def setNeutralize(self, value=1): self._should_neutralize = value
[docs] def setAddAlchemicalIons(self, value=1): self._add_alchemical_ions = value
[docs] def setUseAlchemicalWater(self, value=1): self._use_alchemical_water = value
[docs] def setRemoveOverlappedCrystalWater(self, value: int): self._remove_overlapped_crystal_water = value
[docs] def setRemoveOverlappedSolvent(self, value: int): self._remove_overlapped_solvent = value
[docs] def addIons(self, ion_type='positive', nion=0): self.setNeutralize(0) self.ion_type = ion_type self.nion = nion
[docs] def addSalt(self, c=0.0): """ Add salt at a target concentration. NOTE: In case of FEP inputs for membrane systems, the receptor may already contain salt ions. In this case we will adjust the target concentration to account for these ions. If the intput system concentration is above the target concentration, salt concentration will be set to 0.0 """ self.salt_concentration = c if self.salt_concentration == 0.0: return # Adjust ion concentration if the system already contains salt ions. if not self.solute_st and self.solute_fname: self.fixSolute() # get number of waters nwaters = None # Since the inputs contain water box and membrane CTs, the variable # name is inaccurate and `self.solute_st` will contain solvent CTs. for st in self.solute_st: if st.property.get(CT_TYPE) == CT_TYPE.VAL.SOLVENT: # NOTE: ghost waters should not be part of this CT nwaters = st.mol_total break if nwaters: pos_salt_ions, neg_salt_ions = 0, 0 pos_ion = self.salt_positive_ion.strip('"')[:-4] neg_ion = self.salt_negative_ion.strip('"')[:-4] for st in self.solute_st: pos_salt_ions += len(evaluate_asl(st, f'a.e {pos_ion}')) neg_salt_ions += len(evaluate_asl(st, f'a.e {neg_ion}')) # molarity of pure water is 55.5 pos_salt_concentr = 55.5 * pos_salt_ions / nwaters neg_salt_concentr = 55.5 * neg_salt_ions / nwaters current_salt_concentr = max(pos_salt_concentr, neg_salt_concentr) if current_salt_concentr < self.salt_concentration: self.salt_concentration -= current_salt_concentr else: print('WARNING: Skip adding salt as the current concentration ' f'is {current_salt_concentr:0.2f} M, which is greater ' f'than the target of {self.salt_concentration} M.') self.salt_concentration = 0.0
[docs] def setExcludeLocation(self, value, distance): if type(value) is not list: print('Argument must be list of list type.') sys.exit(1) if len(value) == 0: return self._exclude_location = value self._exclude_distance = distance
[docs] def setIonLocation(self, value): if type(value) is not list: print('Argument must be list of list type.') sys.exit(1) if len(value) == 0: return for v in value: if type(v) is not list: print('Argument must be list of list type.') sys.exit(1) self._ion_location = value
[docs] def setSolvate(self, value=1): self._should_solvate = value
[docs] def setBoundaryCondition(self, **kwargs): if 'use_buffer' in kwargs: self.use_buffer = kwargs['use_buffer'] if 'boundary_condition' in kwargs: self.boundary_condition = kwargs['boundary_condition'] if 'a' in kwargs: self.a = kwargs['a'] if 'b' in kwargs: self.b = kwargs['b'] if 'c' in kwargs: self.c = kwargs['c'] if 'alpha' in kwargs: self.alpha = kwargs['alpha'] if 'beta' in kwargs: self.beta = kwargs['beta'] if 'gamma' in kwargs: self.gamma = kwargs['gamma']
[docs] def setWriteOneMaeFile(self, name='-1'): self.one_mae_file = name
[docs] def setWriteMaeFile(self, name='-1'): self.mae_file = name
[docs] def setWriteMaeffFile(self, name='-1'): self.maeff_file = name
[docs] def setWriteXyzFile(self, name='-1'): self.xyz_file = name
[docs] def setWritePdbFile(self, name='-1'): self.pdb_file = name
[docs] def setWriteTopFile(self, name='-1'): self.top_file = name
[docs] def setWriteG96File(self, name='-1'): self.g96_file = name
[docs] def write(self, name): yes_no = lambda val: self.YES if val else self.NO if self.solute_st: try: solute_fname = os.path.basename(self.solute_fname) base = solute_fname.rindex(".mae") root = solute_fname[:base] ext = solute_fname[base:] solute_fname = root + '_sb' + ext solute_fname = solute_fname.lstrip('"').rstrip('"') except: print("Unrecognized file format for file %s" % solute_fname) sys.exit(1) if os.path.exists(solute_fname): os.remove(solute_fname) for st in self.solute_st: st.append(solute_fname) self.solute_fname = solute_fname if self.membrane == '': self.membrane = 'DPPC.mae.gz' if self.positive_ion == '': self.positive_ion = 'Na.mae' if self.negative_ion == '': self.negative_ion = 'Cl.mae' if self.salt_positive_ion == '': self.salt_positive_ion = 'Na.mae' if self.salt_negative_ion == '': self.salt_negative_ion = 'Cl.mae' input_line = '{\n' if self.oplsaa_version: input_line += ' set_oplsaa_version_as %s\n' % self.oplsaa_version if self.vdw_scaling_factor != -1.0: input_line += ' vdw_scaling_factor %f\n' % self.vdw_scaling_factor if self.mmfepio_map_mode_option != -1: input_line += ' mmfepio_map_mode_option %d\n' % self.mmfepio_map_mode_option if self.mmfepio_retain_angle_option != -1: input_line += ' mmfepio_retain_angle_option %d\n' % self.mmfepio_retain_angle_option if self.solute_alignment_type == 'xyz' and self.solute_alignment_value: input_line += ' align_principal_axes_with_xyz Yes\n' elif self.solute_alignment_type == 'xyz' and not self.solute_alignment_value: input_line += ' align_principal_axes_with_xyz No\n' elif self.solute_alignment_type == 'diagonal' and self.solute_alignment_value: input_line += ' align_principal_axis_with_diagonal Yes\n' elif self.solute_alignment_type == 'diagonal' and not self.solute_alignment_value: input_line += ' align_principal_axis_with_xyz No\n' elif self.solute_alignment_type == 'rezero' and self.solute_alignment_value: input_line += ' rezero_to_center_of_mass Yes\n' elif self.solute_alignment_type == 'rezero' and not self.solute_alignment_value: input_line += ' rezero_to_center_of_mass No\n' if self.solute_fname != '': input_line += ' read_solute_structure "%s"\n' % self.solute_fname if self.solvent and self._should_solvate: input_line += ' solvent_desmond_oplsaa_typer {\n' input_line += ' input_file_name "%s"\n' % ( self.solvent.strip('"')) input_line += ' run\n' input_line += ' }\n' if self._should_membranize: input_line += ' vdw_scaling_factor_membrane 0.25\n' input_line += ' membranize "%s" %f %f\n' % (self.membrane.strip( '"'), self.x_membrane_patch, self.y_membrane_patch) if self.use_buffer: input_line += ' create_boundary_conditions ' else: input_line += ' boundary_conditions ' if (self.boundary_condition == 'cubic'): input_line += 'cubic ' input_line += '%f\n' % float(self.a) elif (self.boundary_condition == 'orthorhombic'): input_line += 'orthorhombic ' input_line += '%f %f %f\n' % (float(self.a), float( self.b), float(self.c)) elif (self.boundary_condition == 'triclinic'): input_line += 'triclinic ' input_line += '%f %f %f %f %f %f\n' % (float(self.a), float( self.b), float(self.c), float(self.alpha), float( self.beta), float(self.gamma)) elif (self.boundary_condition == 'truncated_octahedron'): if self.use_buffer: input_line += 'truncated_octahedron ' input_line += '%f 70.53 109.47 70.53\n' % float(self.a) else: input_line += 'triclinic ' input_line += '%f %f %f 70.53 109.47 70.53\n' % (float( self.a), float(self.a), float(self.a)) elif (self.boundary_condition == 'dodecahedron_square'): if self.use_buffer: input_line += 'dodecahedron_square ' input_line += '%f 60.0 60.0 90.0\n' % float(self.a) else: input_line += 'triclinic ' input_line += '%f %f %f 60.0 60.0 90.0\n' % (float( self.a), float(self.a), float(self.a)) elif (self.boundary_condition == 'dodecahedron_hexagon'): if self.use_buffer: input_line += 'dodecahedron_hexagon ' input_line += '%f 60.0 60.0 60.0\n' % float(self.a) else: input_line += 'triclinic ' input_line += '%f %f %f 60.0 60.0 60.0\n' % (float( self.a), float(self.a), float(self.a)) else: print(self.boundary_condition + ' is not recognizable.') sys.exit(1) if (self.nion > 0 or self._should_neutralize or self._add_alchemical_ions): input_line += ' positive_ion_desmond_oplsaa_typer {\n' input_line += ' input_file_name "%s"\n' % self.positive_ion.strip( '"') input_line += ' run\n' input_line += ' }\n' input_line += ' negative_ion_desmond_oplsaa_typer {\n' input_line += ' input_file_name "%s"\n' % self.negative_ion.strip( '"') input_line += ' run\n' input_line += ' }\n' if self._should_neutralize: input_line += ' neutralize\n' elif self.nion: input_line += ' add_ion %s %d\n' % (self.ion_type, self.nion) if self._add_alchemical_ions: if self._use_alchemical_water: input_line += ' use_alchemical_water Yes\n' input_line += ' add_alchemical_ions\n' if len(self._exclude_location) > 0: input_line += ' exclude_ion_from { ' for a in self._exclude_location: input_line += str(a) + ' ' input_line += '} ' input_line += str(self._exclude_distance) + '\n' if len(self._ion_location) > 0: input_line += ' ion_location {\n' for a in self._ion_location: input_line += ' { ' for b in a: input_line += str(b) + ' ' input_line += '}\n' input_line += ' }\n' if self.salt_concentration > 0.0: input_line += ' salt_positive_ion_desmond_oplsaa_typer {\n' input_line += ' input_file_name "%s"\n' % self.salt_positive_ion.strip( '"') input_line += ' run\n' input_line += ' }\n' input_line += ' salt_negative_ion_desmond_oplsaa_typer {\n' input_line += ' input_file_name "%s"\n' % self.salt_negative_ion.strip( '"') input_line += ' run\n' input_line += ' }\n' input_line += ' add_salt %f\n' % self.salt_concentration input_line += (' %s %s\n' % (self.CHECK_CRYSTAL_WATER_OVERLAP, yes_no(self._remove_overlapped_crystal_water))) input_line += (' %s %s\n' % (self.CHECK_SOLVENT_OVERLAP, yes_no(self._remove_overlapped_solvent))) if self._should_solvate: input_line += ' solvate\n' if (os.path.exists(name)): os.remove(name) base = name index = name.rfind('.csb') if index > 0: base = name[:index] if self.one_mae_file == '-1': input_line += ' write_one_mae_file %s\n' % (base + '-out.mae') elif len(self.one_mae_file) > 0: input_line += ' write_one_mae_file %s\n' % self.one_mae_file if self.mae_file == '-1': input_line += ' write_mae_file "%s"\n' % (base + '.mae').strip('"') elif len(self.mae_file) > 0: input_line += ' write_mae_file "%s"\n' % self.mae_file.strip('"') if self.maeff_file == '-1': input_line += ' write_maeff_file "%s"\n' % (base + '-out.cms').strip('"') elif len(self.maeff_file) > 0: input_line += ' write_maeff_file "%s"\n' % self.maeff_file.strip( '"') if self.pdb_file == '-1': input_line += ' write_pdb_file %s\n' % (base + '.pdb') elif len(self.pdb_file) > 0: input_line += ' write_pdb_file %s\n' % self.pdb_file if self.xyz_file == '-1': input_line += ' write_xyz_file %s\n' % (base + '.xyz') elif len(self.xyz_file) > 0: input_line += ' write_xyz_file %s\n' % self.xyz_file if self.top_file == '-1': input_line += ' write_gromacs_topology %s\n' % (base + '.top') elif len(self.top_file) > 0: input_line += ' write_gromacs_topology %s\n' % self.top_file if self.g96_file == '-1': input_line += ' write_g96_file %s\n' % (base + '.g96') elif len(self.g96_file) > 0: input_line += ' write_g96_file %s\n' % self.g96_file input_line += '}\n' with open(name, 'w') as f: f.write(input_line) return self.solute_fname
[docs] def read(self, name): if (not os.path.exists(name)): print(name + ' does not exist.') sys.exit(1) with open(name, 'r') as f: lines = f.readlines() text = ''.join(lines) text = re.sub(r'#.*\n', '\n', text) self.read_text(text)
[docs] def read_text(self, text): is_val_in = lambda val: (val in all_words ) and f'{val} {self.YES}' in text all_words = set(text.split()) text = text.replace('\r', '') a = re.findall( r'solvent_desmond_oplsaa_typer\s+\{\s+input_file_name\s+(.*)\n', text) if len(a) > 0: self.solvent = a[-1] else: self.solvent = None a = re.findall( r'(^|\s+)positive_ion_desmond_oplsaa_typer\s+\{\s+input_file_name\s+(.*)\n', text) if len(a) > 0: self.positive_ion = a[0][-1] a = re.findall( r'(^|\s+)negative_ion_desmond_oplsaa_typer\s+\{\s+input_file_name\s+(.*)\n', text) if len(a) > 0: self.negative_ion = a[0][-1] a = re.findall( r'salt_positive_ion_desmond_oplsaa_typer\s+\{\s+input_file_name\s+(.*)\n', text) if len(a) > 0: self.salt_positive_ion = a[-1] a = re.findall( r'salt_negative_ion_desmond_oplsaa_typer\s+\{\s+input_file_name\s+(.*)', text) if len(a) > 0: self.salt_negative_ion = a[-1] a = re.findall(r'membranize\s+(".*?"|\S+)\s+(\S+)\s+(\S+)', text) if len(a) > 0: self._should_membranize = 1 self.membrane = a[-1][0] self.x_membrane_patch = float(a[-1][1]) self.y_membrane_patch = float(a[-1][2]) # ensure to find whole word, not something like "haha_neutralize_" self._should_neutralize = int('neutralize' in all_words) self._add_alchemical_ions = int('add_alchemical_ions' in all_words) self._use_alchemical_water = int('use_alchemical_water' in all_words) self._remove_overlapped_crystal_water = int( is_val_in(self.CHECK_CRYSTAL_WATER_OVERLAP)) self._remove_overlapped_solvent = int( is_val_in(self.CHECK_SOLVENT_OVERLAP)) # ensure to find whole word, not something like "haha_solvate_" self._should_solvate = int('solvate' in all_words) a = re.findall(r'add_ion\s+(\S+)\s+(\S+)', text) if len(a) > 0: self.addIons(a[-1][0], int(a[-1][1])) a = re.findall(r'read_solute_structure\s+(.*)\n', text) if len(a) > 0: self.solute_fname = a[-1] a = re.findall(r'add_salt\s+(\S+)', text) if len(a) > 0: self.addSalt(float(a[0])) a = re.findall(r'exclude_ion_from\s+\{(.*)\}\s+(\S+)', text) if len(a) > 0: self._exclude_location = a[-1][0].split() self._exclude_distance = float(a[-1][1]) a = re.findall(r'ion_location\s+\{\s*(\{.*\})\s*\}', text, re.DOTALL) if len(a) > 0: m = a[0] a = re.findall(r'\{\s*(.*?)\s*\}', m, re.DOTALL) self._ion_location = [] for b in a: self._ion_location.append(b.split()) a = re.findall(r'align_principal_axes_with_xyz\s+(\S+)', text) if len(a) > 0: self.solute_alignment_type = 'xyz' self.solute_alignment_value = 1 if str(a[-1]).capitalize() == "NO": self.solute_alignment_value = 0 a = re.findall(r'rezero_to_center_of_mass\s+(\S+)', text) if len(a) > 0: self.solute_alignment_type = 'rezero' self.solute_alignment_value = 1 if str(a[-1]).upper() == "NO": self.solute_alignment_value = 0 a = re.findall(r'set_oplsaa_version_as\s+(\S+)', text) if len(a) > 0: self.oplsaa_version = a[-1] a = re.findall(r'vdw_scaling_factor\s+(\S+)', text) if len(a) > 0: self.vdw_scaling_factor = float(a[-1]) a = re.findall(r'mmfepio_map_mode_option\s+(\S+)', text) if len(a) > 0: self.mmfepio_map_mode_option = int(a[-1]) a = re.findall(r'mmfepio_retain_angle_option\s+(\S+)', text) if len(a) > 0: self.mmfepio_retain_angle_option = int(a[-1]) a = re.findall(r'write_mae_file\s+(\S+)', text) if len(a) > 0: self.mae_file = a[-1] a = re.findall(r'write_maeff_file\s+(.*)\n', text) if len(a) > 0: self.maeff_file = a[-1] a = re.findall(r'write_pdb_file\s+(\S+)', text) if len(a) > 0: self.pdb_file = a[-1] a = re.findall(r'write_xyz_file\s+(\S+)', text) if len(a) > 0: self.xyz_file = a[-1] a = re.findall(r'write_gromacs_topology\s+(\S+)', text) if len(a) > 0: self.top_file = a[-1] a = re.findall(r'write_g96_file\s+(\S+)', text) if len(a) > 0: self.g96_file = a[-1] a = re.findall(r'(^|\s+)boundary_conditions(\s+)', text) if len(a) > 0: self.use_buffer = 0 a = re.findall(r'create_boundary_conditions(\s+)', text) if len(a) > 0: self.use_buffer = 1 a = re.findall(r'boundary_conditions\s+cubic\s+(\S+)', text) if len(a) > 0: self.boundary_condition = 'cubic' self.a = a[0] a = re.findall(r'boundary_conditions\s+orthorhombic\s+(.*)', text) if len(a) > 0: a = a[0].split() self.boundary_condition = 'orthorhombic' self.a = float(a[0]) self.b = float(a[1]) self.c = float(a[2]) a = re.findall(r'boundary_conditions\s+triclinic\s+(.*)', text) if len(a) > 0: a = a[0].split() self.boundary_condition = 'triclinic' self.a = float(a[0]) self.b = float(a[1]) self.c = float(a[2]) self.alpha = float(a[3]) self.beta = float(a[4]) self.gamma = float(a[5]) a = re.findall(r'boundary_conditions\s+truncated_octahedron\s+(.*)', text) if len(a) > 0: a = a[0].split() self.boundary_condition = 'truncated_octahedron' self.a = float(a[0]) self.alpha = float(a[1]) self.beta = float(a[2]) self.gamma = float(a[3]) a = re.findall(r'boundary_conditions\s+dodecahedron_square\s+(.*)', text) if len(a) > 0: a = a[0].split() self.boundary_condition = 'dodecahedron_square' self.a = float(a[0]) self.alpha = float(a[1]) self.beta = float(a[2]) self.gamma = float(a[3]) a = re.findall(r'boundary_conditions\s+dodecahedron_hexagon\s+(.*)', text) if len(a) > 0: a = a[0].split() self.boundary_condition = 'dodecahedron_hexagon' self.a = float(a[0]) self.alpha = float(a[1]) self.beta = float(a[2]) self.gamma = float(a[3])
[docs] @staticmethod def identifySolventAtoms(st, asl=None): return evaluate_asl(st, asl) if asl \ else smarts.evaluate_net_smarts(st, water_smarts, zob_water_smarts)
[docs] def extractSolventFromSt(self, st, asl=''): water_st = None water_atoms = self.identifySolventAtoms(st, asl) if len(water_atoms) == 0 or len(water_atoms) == st.atom_total: return None water_st = st.extract(water_atoms) renumber_map = st.deleteAtoms(water_atoms, renumber_map=True) if self._exclude_location: # The atom index may change after exracting waters. Update the # `exclude_location` after the atoms are deleted. DESMOND-10210 self._exclude_location = [ renumber_map[i] for i in self._exclude_location ] water_st.property[CT_TYPE] = CT_TYPE.VAL.CRYSTAL_WATER water_st.property[NUM_COMPONENT] = 1 new_st = water_st.copy() reorder = [0] for m in water_st.molecule: for i in m.getAtomIndices(): reorder.append(i) mm.mmct_ct_reorder(new_st, water_st, reorder) return new_st
[docs] def deleteSolventFromSt(self, st, asl=''): water_atoms = self.identifySolventAtoms(st, asl) nwater = len(water_atoms) if nwater > 0 and (nwater != st.atom_total): st.deleteAtoms(water_atoms)
[docs] def treatSolventFromSolute(self, op='separate', asl=''): if op not in set(['separate', 'delete']): print('Operation, %s, is not defined.' % op) sys.exit(1) crystal_water_st = None for st in self.solute_st: temp_st = self.extractSolventFromSt(st, asl) if temp_st: if crystal_water_st: crystal_water_st.merge(temp_st) else: crystal_water_st = temp_st if crystal_water_st and op == 'separate': self.solute_st.append(crystal_water_st)
[docs] def run(self, name='desmond_setup', options=[]): # noqa: M511 input_file_name = name + '.csb' self.write(input_file_name) sb_cmd = os.path.join(os.environ["SCHRODINGER"], "utilities", "system_builder") if (not os.path.exists(sb_cmd)): print('%s does not exist.' % sb_cmd) sys.exit(1) if (os.path.expandvars("$PYTHONHOME") != "$PYTHONHOME"): del (os.environ['PYTHONHOME']) cmd = [ sb_cmd, input_file_name, ] cmd.extend(options) job_log = "Starting system builder" job_log += "\n" job_log += "Job name: " + name job_log += "\n" print(job_log) job_obj = jobcontrol.launch_job(cmd) job_id = job_obj.job_id.strip() job_log = "Job ID: " + job_id job_log += "\n" print(job_log)
if __name__ == "__main__": a = SystemBuilderInput() a.setSolute('/zone1/kim/chorus/membrane/1cyo.mae') a.treatSolventFromSolute() a.run('babo') a.read('babo.csb') a.setSoluteAlignment('xyz') a.setNeutralize(1) a.setBoundaryCondition(use_buffer=1, boundary_condition='triclinic', a=10.0, b=10.0, c=10.0, alpha=90.0, beta=90.0, gamma=90.0) a.setSolvent('tip4p.box.mae') a.run('babo2')