from __future__ import division from __future__ import print_function import math import Source.lib as lib import sys, os # names and types of all key words in configuration file matrices = ['interaction_matrix'] pair_wise_matrices = ['sidechain_cutoffs'] number_dictionaries = ['VanDerWaalsVolume','charge','model_pkas','ions', 'valence_electrons','custom_model_pkas'] list_dictionaries = ['backbone_NH_hydrogen_bond','backbone_CO_hydrogen_bond'] string_dictionaries = ['protein_group_mapping'] string_lists = ['ignore_residues','angular_dependent_sidechain_interactions', 'acid_list','base_list','exclude_sidechain_interactions', 'backbone_reorganisation_list','write_out_order'] distances = ['desolv_cutoff','buried_cutoff','coulomb_cutoff1','coulomb_cutoff2'] parameters = ['Nmin','Nmax','desolvationSurfaceScalingFactor','desolvationPrefactor', 'desolvationAllowance','coulomb_diel','COO_HIS_exception','OCO_HIS_exception', 'CYS_HIS_exception','CYS_CYS_exception','min_ligand_model_pka','max_ligand_model_pka', 'include_H_in_interactions','coupling_max_number_of_bonds', 'min_bond_distance_for_hydrogen_bonds','coupling_penalty', 'shared_determinants','common_charge_centre','hide_penalised_group', 'remove_penalised_group', 'max_intrinsic_pKa_diff','min_interaction_energy','max_free_energy_diff','min_swap_pka_shift', 'min_pka','max_pka','sidechain_interaction'] strings = ['version','output_file_tag','ligand_typing','pH','reference'] class Parameters: def __init__(self, parameter_file): self.set_up_data_structures() self.read_parameters(parameter_file) #self.print_interaction_parameters() #self.print_interaction_parameters_latex() #####self.print_interactions_latex() #sys.exit(0) return def read_parameters(self, file): # try to locate the parameters file try: path = os.path.dirname(__file__) ifile = os.path.join(path,'../'+file) input = lib.open_file_for_reading(ifile) except: input = lib.open_file_for_reading(file) for line in input: self.parse_line(line) return def parse_line(self, line): # first, remove comments comment_pos = line.find('#') if comment_pos != -1: line = line[:comment_pos] # split the line into words words = line.split() if len(words) == 0: return # parse the words if len(words)==3 and words[0] in number_dictionaries: self.parse_to_number_dictionary(words) elif len(words)==2 and words[0] in string_lists: self.parse_to_string_list(words) elif len(words)==2 and words[0] in distances: self.parse_distance(words) elif len(words)==2 and words[0] in parameters: self.parse_parameter(words) elif len(words)==2 and words[0] in strings: self.parse_string(words) elif len(words)>2 and words[0] in list_dictionaries: self.parse_to_list_dictionary(words) elif words[0] in matrices+pair_wise_matrices: self.parse_to_matrix(words) elif len(words)==3 and words[0] in string_dictionaries: self.parse_to_string_dictionary(words) #print(words) return def parse_to_number_dictionary(self, words): exec('self.%s[\'%s\'] = %s'%tuple(words)) return def parse_to_string_dictionary(self, words): exec('self.%s[\'%s\'] = \'%s\''%tuple(words)) return def parse_to_list_dictionary(self, words): exec('if not \'%s\' in self.%s.keys(): self.%s[\'%s\'] = []'%(words[1],words[0],words[0],words[1])) for word in words[2:]: exec('self.%s[\'%s\'].append(%s)'%(words[0],words[1],word)) return def parse_to_string_list(self, words): exec('self.%s.append(\'%s\')'%tuple(words)) return def parse_to_matrix(self, words): exec('self.%s.add(%s)'%(words[0],tuple(words[1:]))) return def parse_distance(self, words): # float check needed exec('self.%s = %s'%tuple(words)) exec('self.%s_squared = pow(%s,2)'%tuple(words)) return def parse_parameter(self, words): exec('self.%s = %s'%tuple(words)) return def parse_string(self, words): #print('self.%s = \'%s\''%tuple(words)) exec('self.%s = \'%s\''%tuple(words)) return def set_up_data_structures(self): for key_word in number_dictionaries+list_dictionaries+string_dictionaries: exec('self.%s = {}'%key_word) for key_word in string_lists: exec('self.%s = []'%key_word) for key_word in strings: exec('self.%s = \'\''%key_word) for key_word in matrices: exec('self.%s = Interaction_matrix(\'%s\')'%(key_word,key_word)) for key_word in pair_wise_matrices: exec('self.%s =Pair_wise_matrix(\'%s\')'%(key_word,key_word)) return def print_interaction_parameters(self): print('--------------- Model pKa values ----------------------') for k in self.model_pkas.keys(): print('%3s %8.2f'%(k,self.model_pkas[k])) print('') print('--------------- Interactions --------------------------') agroups = ['COO', 'HIS', 'CYS', 'TYR', 'SER', 'N+', 'LYS', 'AMD', 'ARG', 'TRP', 'ROH', 'CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH'] lgroups = ['CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH'] map = { 'CG' :['ARG'], 'C2N':['ARG'], 'N30':['N+','LYS'], 'N31':['N+','LYS'], 'N32':['N+','LYS'], 'N33':['N+','LYS'] , 'NAR':['HIS'], 'OCO':['COO'], 'OP' :[],#['TYR','SER'], 'SH' :['CYS'] , 'NP1':[], 'OH' :['ROH'], 'O3' :[] , 'CL' :[], 'F' :[], 'NAM':['AMD'], 'N1' :[], 'O2' :[]} for g1 in agroups: for g2 in lgroups: interaction = '%3s %3s %1s %4s %4s'%(g1,g2, self.interaction_matrix[g1][g2], self.sidechain_cutoffs.get_value(g1,g2)[0], self.sidechain_cutoffs.get_value(g1,g2)[1]) map_interaction = '' if g2 in map: for m in map[g2]: map_interaction += '|%3s %3s %1s %4s %4s'%(g1,m, self.interaction_matrix[g1][m], self.sidechain_cutoffs.get_value(g1,m)[0], self.sidechain_cutoffs.get_value(g1,m)[1]) if self.interaction_matrix[g1][m] != self.interaction_matrix[g1][g2]: map_interaction += '* ' if self.sidechain_cutoffs.get_value(g1,m)[0] != self.sidechain_cutoffs.get_value(g1,g2)[0] or \ self.sidechain_cutoffs.get_value(g1,m)[1] != self.sidechain_cutoffs.get_value(g1,g2)[1]: map_interaction += '! ' else: map_interaction += ' ' if len(map[g2])==0 and (self.sidechain_cutoffs.get_value(g1,g2)[0] !=3 or self.sidechain_cutoffs.get_value(g1,g2)[1] != 4): map_interaction += '? ' print(interaction,map_interaction ) if g1==g2: break print('-') print('--------------- Exceptions ----------------------------') print('COO-HIS',self.COO_HIS_exception) print('OCO-HIS',self.OCO_HIS_exception) print('CYS-HIS',self.CYS_HIS_exception) print('CYS-CYS',self.CYS_CYS_exception) print('--------------- Mapping -------------------------------') print(""" Titratable: CG ARG C2N ARG N30 N+/LYS N31 N+/LYS N32 N+/LYS N33 N+/LYS NAR HIS OCO COO OP TYR/SER? SH CYS Non-titratable: NP1 AMD? OH ROH O3 ? CL F NAM N1 O2 """) return def print_interaction_parameters_latex(self): # print('--------------- Model pKa values ----------------------') # for k in self.model_pkas.keys(): # print('%3s %8.2f'%(k,self.model_pkas[k])) # print('') # print('--------------- Interactions --------------------------') agroups = ['COO', 'HIS', 'CYS', 'TYR', 'SER', 'N+', 'LYS', 'AMD', 'ARG', 'TRP', 'ROH', 'CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH'] lgroups = ['CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH'] map = { 'CG' :['ARG'], 'C2N':['ARG'], 'N30':['N+','LYS'], 'N31':['N+','LYS'], 'N32':['N+','LYS'], 'N33':['N+','LYS'] , 'NAR':['HIS'], 'OCO':['COO'], 'OP' :[],#['TYR','SER'], 'SH' :['CYS'] , 'NP1':['AMD'], 'OH' :['ROH'], 'O3' :[] , 'CL' :[], 'F' :[], 'NAM':[], 'N1' :[], 'O2' :[]} s = """ \\begin{longtable}{lllll} \\caption{Ligand interaction parameters. For interactions not listed, the default value of %s is applied.} \\label{tab:ligand_interaction_parameters}\\\\ \\toprule Group1 & Group2 & Interaction & c1 &c2 \\\\ \\midrule \\endfirsthead \\multicolumn{5}{l}{\\emph{continued from the previous page}}\\\\ \\toprule Group1 & Group2 & Interaction & c1 &c2 \\\\ \\midrule \\endhead \\midrule \\multicolumn{5}{r}{\\emph{continued on the next page}}\\\\ \\endfoot \\bottomrule \\endlastfoot """%(self.sidechain_cutoffs.default) for g1 in agroups: for g2 in lgroups: if self.interaction_matrix[g1][g2]=='-': continue if self.sidechain_cutoffs.get_value(g1,g2)==self.sidechain_cutoffs.default: continue s+= '%3s & %3s & %1s & %4s & %4s\\\\ \n'%(g1,g2, self.interaction_matrix[g1][g2], self.sidechain_cutoffs.get_value(g1,g2)[0], self.sidechain_cutoffs.get_value(g1,g2)[1]) if g1==g2: break s += ' \\end{longtable}\n' print(s) return def print_interactions_latex(self): agroups = ['COO', 'HIS', 'CYS', 'TYR', 'SER', 'N+', 'LYS', 'AMD', 'ARG', 'TRP', 'ROH', 'CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH'] lgroups = ['CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH'] s = """ \\begin{longtable}{%s} \\caption{Ligand interaction parameters. For interactions not listed, the default value of %s is applied.} \\label{tab:ligand_interaction_parameters}\\\\ \\toprule Group1 & Group2 & Interaction & c1 &c2 \\\\ \\midrule \\endfirsthead \\multicolumn{5}{l}{\\emph{continued from the previous page}}\\\\ \\toprule Group1 & Group2 & Interaction & c1 &c2 \\\\ \\midrule \\endhead \\midrule \\multicolumn{5}{r}{\\emph{continued on the next page}}\\\\ \\endfoot \\bottomrule \\endlastfoot """%('l'*len(agroups),self.sidechain_cutoffs.default) for g1 in agroups: for g2 in agroups: s+= '%3s & %3s & %1s & %4s & %4s\\\\ \n'%(g1,g2, self.interaction_matrix[g1][g2], self.sidechain_cutoffs.get_value(g1,g2)[0], self.sidechain_cutoffs.get_value(g1,g2)[1]) if g1==g2: break s += ' \\end{longtable}\n' print(s) return class Interaction_matrix: def __init__(self, name): self.name = name self.ordered_keys = [] self.dictionary = {} return def add(self,words): new_group = words[0] self.ordered_keys.append(new_group) if not new_group in self.dictionary.keys(): self.dictionary[new_group] = {} for i in range(len(self.ordered_keys)): group = self.ordered_keys[i] if len(words)>i+1: try: exec('self.value = %s'%words[i+1]) except: self.value = words[i+1] self.dictionary[group][new_group] = self.value self.dictionary[new_group][group] = self.value return def get_value(self, item1, item2): try: return self.dictionary[item1][item2] except: return None def __getitem__(self, group): if group not in self.dictionary.keys(): raise Exception('%s not found in interaction matrix %s'%(group,self.name)) return self.dictionary[group] def keys(self): return self.dictionary.keys() def __str__(self): s = ' ' for k1 in self.ordered_keys: s+='%3s '%k1 s+='\n' for k1 in self.ordered_keys: s+='%3s '%k1 for k2 in self.ordered_keys: s+='%3s '%self[k1][k2] s+='\n' return s # ks = ['COO', 'SER', 'ARG', 'LYS', 'HIS', 'AMD', 'CYS', 'TRP','ROH','TYR','N+','CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH'] # p = '' # n=0 # for i in range(len(ks)): # for j in range(i,len(ks)): # if not [0.0,0.0]==self[ks[i]][ks[j]]: # if not [3.0,4.0]==self[ks[i]][ks[j]]: # p+='sidechain_cutoff %3s %3s %s\n'%(ks[i],ks[j],self[ks[i]][ks[j]]) # n+=1 # print('total',n,len(ks)) # return p class Pair_wise_matrix: def __init__(self, name): self.name = name self.dictionary = {} self.default = [0.0, 0.0] return def add(self,words): # assign the default value if len(words)==3 and words[0]=='default': self.default = [float(words[1]), float(words[2])] return # assign non-default values g1 = words[0] g2 = words[1] v = [float(words[2]), float(words[3])] self.insert(g1,g2,v) self.insert(g2,g1,v) return def insert(self, k1,k2,v): if k1 in self.dictionary.keys() and k2 in self.dictionary[k1].keys(): if k1!=k2: print ('Warning: Paramter value for %s, %s defined more than once'%(k1,k2)) if not k1 in self.dictionary: self.dictionary[k1] = {} self.dictionary[k1][k2] =v return def get_value(self, item1, item2): try: return self.dictionary[item1][item2] except: return self.default def __getitem__(self, group): if group not in self.dictionary.keys(): raise Exception('%s not found in interaction matrix %s'%(group,self.name)) return self.dictionary[group] def keys(self): return self.dictionary.keys() def __str__(self): s='' for k1 in self.keys(): for k2 in self[k1].keys(): s += '%s %s %s\n'%(k1,k2,self[k1][k2]) return s