diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml new file mode 100644 index 00000000..44645cf2 --- /dev/null +++ b/.github/workflows/python-package.yml @@ -0,0 +1,43 @@ +# This workflow will install Python dependencies, run tests and lint with a variety of Python versions +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python + +name: Python package + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.10",] + + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install flake8 pytest + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Lint with flake8 + run: | + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Build and install with setuptools + run: | + python setup.py install + - name: Test with pytest + run: | + pytest example_scripts/ diff --git a/example_scripts/test_build.py b/example_scripts/test_build.py index f7423456..1f1ba461 100644 --- a/example_scripts/test_build.py +++ b/example_scripts/test_build.py @@ -1,52 +1,52 @@ -from pmx import * +from pmx import Molecule, Chain +from pmx.builder import build_dna_strand -# start a peptide chain from an amino acid -mol = Molecule().new_aa( "ALA" ) # build alanine -c = Chain( residues = [ mol ] ) # initialize chain -c.nbuild("T") # extend at n-terminus -c.cbuild("R") # extend at c-terminus -c.write('TAR.pdb') # write pdb file +def test_build(): + # start a peptide chain from an amino acid + mol = Molecule().new_aa( "ALA" ) # build alanine + c = Chain( residues = [ mol ] ) # initialize chain + c.nbuild("T") # extend at n-terminus + c.cbuild("R") # extend at c-terminus + c.write('TAR.pdb') # write pdb file -# build a peptide chain from sequence + # build a peptide chain from sequence -sequence = "FRTLKNCWQ" -c = Chain().create( sequence ) -c.write("extended.pdb") + sequence = "FRTLKNCWQ" + c = Chain().create( sequence ) + c.write("extended.pdb") -for resi in c.residues: - resi.set_phi( -57, True ) - resi.set_psi( -47, True ) -c.write("helix_pep.pdb") + for resi in c.residues: + resi.set_phi( -57, True ) + resi.set_psi( -47, True ) + c.write("helix_pep.pdb") -# fusing two chains -seq = "LMNFRTS" -c2 = Chain().create(seq) -c.fuse( c2 ) -c.write("fused_pep.pdb") + # fusing two chains + seq = "LMNFRTS" + c2 = Chain().create(seq) + c.fuse( c2 ) + c.write("fused_pep.pdb") -# create repeating seuqences + # create repeating seuqences -rep_seq = "HEATLLFT" -c = Chain().create( rep_seq ) # start with new chain -new_chain = c.copy() + rep_seq = "HEATLLFT" + c = Chain().create( rep_seq ) # start with new chain + new_chain = c.copy() -for i in range(5): - c.fuse( new_chain.copy() ) -c.write("rep_pep.pdb") -print c.sequence() -helical_residues = c.fetch_residues(["HIS","GLU","ALA","THR","LEU"]) -for resi in helical_residues: - resi.set_phi( -57, True ) - resi.set_psi( -47, True ) -c.write("repeat_helix.pdb") + for i in range(5): + c.fuse( new_chain.copy() ) + c.write("rep_pep.pdb") + print(c.sequence()) + helical_residues = c.fetch_residues(["HIS","GLU","ALA","THR","LEU"]) + for resi in helical_residues: + resi.set_phi( -57, True ) + resi.set_psi( -47, True ) + c.write("repeat_helix.pdb") -# building a DNA strand -from pmx.builder import * -model = build_dna_strand("ACGTGTCA") -model.write("dna.pdb") - + # building a DNA strand + model = build_dna_strand("ACGTGTCA") + model.write("dna.pdb") diff --git a/example_scripts/test_edit.py b/example_scripts/test_edit.py index 022a04f7..e44e041f 100644 --- a/example_scripts/test_edit.py +++ b/example_scripts/test_edit.py @@ -1,44 +1,45 @@ import sys, os -from pmx import * +from pmx import Model, Chain -seq1 = 'klrtsfcvnme'*2 -seq2 = 'irtiervcywq'*2 +def test_edit(): + seq1 = 'klrtsfcvnme'*2 + seq2 = 'irtiervcywq'*2 -c1 = Chain().create( seq1.upper() ) -c2 = Chain().create( seq2.upper() ) -c1.set_chain_id('A') -c2.set_chain_id('B') -c2.translate( [20,0,0] ) -m = Model(chains = [c1,c2] ) -m.write('protein.pdb') -m = Model('protein.pdb') + c1 = Chain().create( seq1.upper() ) + c2 = Chain().create( seq2.upper() ) + c1.set_chain_id('A') + c2.set_chain_id('B') + c2.translate( [20,0,0] ) + m = Model(chains = [c1,c2] ) + m.write('protein.pdb') -for atom in m.atoms: - print atom.id, atom.name, atom.resname - -for resi in m.residues: - if resi.resname in ['ALA','SER']: # select some residues - print resi - for atom in resi.atoms: - print atom.bfac # print some properties + m = Model('protein.pdb') + for atom in m.atoms: + print(atom.id, atom.name, atom.resname) -for c in m.chains: - print c.id, len(c.residues), len(c.atoms) # print chain id, number of - # residues and number of atoms + for resi in m.residues: + if resi.resname in ['ALA','SER']: # select some residues + print(resi) + for atom in resi.atoms: + print(atom.bfac) # print some properties -chainB = m.chdic['B'] # select chain -for atom in chainB.atoms: - print atom.occ + for c in m.chains: + print(c.id, len(c.residues), len(c.atoms)) # print chain id, number of + # residues and number of atoms -resl = m.fetch_residues(["LEU","PHE"]) -for r in resl: - print 'leu_or_phe:', r + chainB = m.chdic['B'] # select chain + for atom in chainB.atoms: + print(atom.occ) -resl = m.fetch_residues(["LEU","PHE"], inv = True) -for r in resl: - print 'not leu_or_phe:', r + resl = m.fetch_residues(["LEU","PHE"]) + for r in resl: + print('leu_or_phe:', r) + + resl = m.fetch_residues(["LEU","PHE"], inv = True) + for r in resl: + print('not leu_or_phe:', r) diff --git a/example_scripts/test_ffparser.py b/example_scripts/test_ffparser.py index 675e3025..e7053be4 100644 --- a/example_scripts/test_ffparser.py +++ b/example_scripts/test_ffparser.py @@ -1,37 +1,38 @@ import sys, os -from pmx.forcefield2 import * +from pmx.forcefield2 import ITPFile -top = ITPFile( sys.argv[1]) -## for atom in top.atoms: -## atom.atomtypeB = 'DUM' -## atom.qB = 0 -## atom.mB = atom.m -top.write('new.itp') +def test_ffparser(): + top = ITPFile('./protLig_benchmark/pde2/ligands_cgenff/lig_50181001/MOL.itp') + ## for atom in top.atoms: + ## atom.atomtypeB = 'DUM' + ## atom.qB = 0 + ## atom.mB = atom.m + top.write('new.itp') -## from pmx.ffparser import * -## ## from pmx.library import _aacids_dic -## rtp = RTPParser( 'ffamber99sb.rtp') -## print rtp['ALA'] -## for name, entry in rtp: -## print name, entry['atoms'][0] -## print 'XXX' -## for name, entry in rtp: -## print name, entry['atoms'][0] -## ala = rtp['ALA'] -## print _aacids_dic -## for aa in _aacids_dic.values(): -## try: -## del rtp[aa] -## except: -## pass -## rtp.add_entry( "ala", ala ) -## print "ala" in rtp -#rtp.write(sys.stdout) -#print rtp["ALA"]['bonds'] + ## from pmx.ffparser import * + ## ## from pmx.library import _aacids_dic + ## rtp = RTPParser( 'ffamber99sb.rtp') + ## print rtp['ALA'] -#nb = NBParser("ffamber99sbnb.itp") -#print nb + ## for name, entry in rtp: + ## print name, entry['atoms'][0] + ## print 'XXX' + ## for name, entry in rtp: + ## print name, entry['atoms'][0] + ## ala = rtp['ALA'] + ## print _aacids_dic + ## for aa in _aacids_dic.values(): + ## try: + ## del rtp[aa] + ## except: + ## pass + ## rtp.add_entry( "ala", ala ) + ## print "ala" in rtp + #rtp.write(sys.stdout) + #print rtp["ALA"]['bonds'] + #nb = NBParser("ffamber99sbnb.itp") + #print nb diff --git a/example_scripts/test_index.py b/example_scripts/test_index.py index 512f02fa..d4b6b34c 100644 --- a/example_scripts/test_index.py +++ b/example_scripts/test_index.py @@ -2,12 +2,16 @@ from pmx import * from pmx.ndx import * -m = Model( "gmx.pdb" ) +m = Model( "./protLig_benchmark/cdk2/ligands_gaff2/lig_1h1q/mol_gmx.pdb" ) + +import pytest +pytest.skip(allow_module_level=True) +# skip because don't have an example .ndx file ndx = IndexFile("index.ndx") -print ndx -print ndx['Backbone'] +print(ndx) +print(ndx['Backbone']) atoms = ndx['Backbone'].select_atoms( m ) del ndx['Backbone'] @@ -17,7 +21,6 @@ -print ndx +print(ndx) #for atom in atoms: # print atom - diff --git a/example_scripts/test_insert.py b/example_scripts/test_insert.py index 59c48d65..f8c6fc45 100644 --- a/example_scripts/test_insert.py +++ b/example_scripts/test_insert.py @@ -1,18 +1,17 @@ import sys, os -from pmx import * +from pmx import Model, Chain -## c = Chain().create("ALKIRTS") +def test_insert(): + c = Chain().create("ALKIRTS") + m = Model("./protLig_benchmark/cdk2/protein_amber/protein.pdb") -## m = Model("protein.pdb") - -## chB = m.chdic["B"] - -## chB.insert_chain(2, c ) -## m.write("ins.pdb") -c = Chain().create("ALT") -print c.atoms[0].name -del c.atoms[0] # delete list item, first atom is gone -print c.atoms[0].name # first atom is a different one now -atom = c.residues[0].atoms[0] # select first atom from the first residue -print atom.name # should be the same as above + chB = m.chdic["B"] + chB.insert_chain(2, c ) + m.write("ins.pdb") + c = Chain().create("ALT") + print(c.atoms[0].name) + del c.atoms[0] # delete list item, first atom is gone + print(c.atoms[0].name) # first atom is a different one now + atom = c.residues[0].atoms[0] # select first atom from the first residue + print(atom.name) # should be the same as above diff --git a/example_scripts/test_new_rot.py b/example_scripts/test_new_rot.py index 5bdfa7a4..7c222b2a 100644 --- a/example_scripts/test_new_rot.py +++ b/example_scripts/test_new_rot.py @@ -6,4 +6,3 @@ r.set_phi( -57, True ) r.set_psi( -47, True ) c.write('hel.pdb') - diff --git a/example_scripts/test_opt.py b/example_scripts/test_opt.py index 42140279..8b87a5fd 100644 --- a/example_scripts/test_opt.py +++ b/example_scripts/test_opt.py @@ -1,3 +1,6 @@ +import pytest +pytest.skip(allow_module_level=True) + import sys, os from pmx import * @@ -13,9 +16,9 @@ file_options = [ - FileOption("-pdb", "r",["pdb"], "protein.pdb", "input pdb file"), - FileOption("-opdb", "w",["pdb","gro"], "out.pdb", "output pdb or gro file"), - FileOption("-mpdb", "r/m",["pdb","gro"], "one_of_many.pdb", "several pdb files"), + FileOption("-pdb", "r",["pdb"], "protein.pdb", "input pdb file"), + FileOption("-opdb", "w",["pdb","gro"], "out.pdb", "output pdb or gro file"), + FileOption("-mpdb", "r/m",["pdb","gro"], "one_of_many.pdb", "several pdb files"), ] help_text = [ "This program does useful things", @@ -23,11 +26,9 @@ "but not in combination with d and e"] -cmdl = Commandline( sys.argv, options = options, fileoptions = file_options, program_desc = help_text, version = "2.3") - - +cmdl = Commandline( sys.argv, options = options, fileoptions = file_options, program_desc = help_text, version = "2.3") -string_opt = cmdl['-s'] -input_pdb = cmdl['-pdb'] +string_opt = cmdl['-s'] +input_pdb = cmdl['-pdb'] diff --git a/example_scripts/test_pml_ndx.py b/example_scripts/test_pml_ndx.py index 1f82b13f..fe797d98 100644 --- a/example_scripts/test_pml_ndx.py +++ b/example_scripts/test_pml_ndx.py @@ -2,6 +2,10 @@ from pmx import * from pmx.ndx import * +import pytest +pytest.skip(allow_module_level=True) +# skip because pymol not installed as dependency + from pymol import cmd, stored @@ -23,20 +27,19 @@ def __sel_from_id_list( name, ids ): cmd.select( name, "ID %d" % ids[0] ) for idx in ids[1:]: cmd.select( name, "%s or ID %d" % (name, idx) ) - + def load_ndx( fname = "index.ndx", names = []): if not os.path.isfile( fname ): return ndx_file = IndexFile( fname ) if not names: names = ndx_file.names for name in names: - print name - if ndx_file.dic.has_key( name ): + print(name) + if name in ndx_file.dic: ids = ndx_file[name].ids __sel_from_id_list( name, ids ) - + cmd.deselect() cmd.extend("write_ndx",write_ndx) cmd.extend("load_ndx",load_ndx) - diff --git a/example_scripts/test_rot.py b/example_scripts/test_rot.py index 454ddfd6..3fe8f0ab 100644 --- a/example_scripts/test_rot.py +++ b/example_scripts/test_rot.py @@ -7,19 +7,18 @@ R = Rotation([0,0,0],[1,0,0]) -m = Model("cdk2.pdb") +m = Model("./protLig_benchmark/cdk2/protein_amber/protein.pdb") -t1 = time.clock() +t1 = time.time() -for r in m.residues: +for i, r in enumerate(m.residues[1:297]): r.set_phi(-139, True) r.set_psi(135, True) ## for i in range(100): ## for atom in m.atoms: ## atom.x = R.apply( atom.x, 60*pi/180.) - -t2 = time.clock() -print t2-t1 -m.write("out2.pdb") +t2 = time.time() +print(t2-t1) +m.write("out2.pdb") diff --git a/example_scripts/test_rotamer.py b/example_scripts/test_rotamer.py index b8736367..9c16fd10 100644 --- a/example_scripts/test_rotamer.py +++ b/example_scripts/test_rotamer.py @@ -2,12 +2,12 @@ from pmx.rotamer import * c = Chain().create("ALARYTK") -print 'done' +print('done') c.add_nterm_cap() c.add_cterm_cap() c.rename_atoms() -print c.sequence() +print(c.sequence()) c.write('x.pdb') ## bbdep = load_bbdep() @@ -21,5 +21,3 @@ ## for i, r in enumerate(rot): ## res.set_conformation( r ) ## c.write("rot%d.pdb" % i ) - - diff --git a/example_scripts/test_xtc.py b/example_scripts/test_xtc.py index c4f44091..02f7b2f8 100644 --- a/example_scripts/test_xtc.py +++ b/example_scripts/test_xtc.py @@ -2,30 +2,32 @@ from pmx.xtc import * import sys, os -m = Model("out.pdb") +m = Model("./protLig_benchmark/cdk2/protein_amber/protein.pdb") -atom1 = m.residues[0]['CA'] # CA-atom of first residues -atom2 = m.residues[-1]['CA'] # CA-atom of last residue -distance_12 = lambda a,b: a-b # function that returns the distance between atom1 and atom2 -fp = open("analysis.dat","w") # open output file +atom1 = m.residues[1]['CA'] # CA-atom of first residues +atom2 = m.residues[297]['CA'] # CA-atom of last residue +distance_12 = lambda a,b: a-b # function that returns the distance between atom1 and atom2 +fp = open("analysis.dat","w") # open output file +import pytest +pytest.skip(allow_module_level=True) +# skip because no .xtc file trj = Trajectory("concoord.xtc") # open xtc file and read first frame -for frame in trj: # go over each frame - print frame # print some info - trj.update( m ) # update coords in model - d = distance_12( atom1, atom2 ) # calculate observable - print >>fp, "%8.3f %8.3f" % (frame.time.value, d ) # store data -fp.close() # close output file -trj.close_xtc() # close xtc +for frame in trj: # go over each frame + print(frame) # print some info + trj.update( m ) # update coords in model + d = distance_12( atom1, atom2 ) # calculate observable + print("%8.3f %8.3f" % (frame.time.value, d ), file=fp) # store data +fp.close() # close output file +trj.close_xtc() # close xtc from pylab import * from pmx.parser import * data = read_and_format("analysis.dat","ff") -time = map( lambda a: a[0], data) -dist = map(lambda a:a[1], data) +time = [a[0] for a in data] +dist = [a[1] for a in data] plot( time, dist, "r-", lw = 2) xlabel( "time [ps]") ylabel(r"end to end distance [$\AA$]") savefig("plot.png") - diff --git a/pmx/__init__.py b/pmx/__init__.py index 8ca8cc38..a9db7ae7 100644 --- a/pmx/__init__.py +++ b/pmx/__init__.py @@ -43,11 +43,11 @@ del get_versions import os -from atom import * -from molecule import * -from chain import * -from model import * -from options import * +from .atom import * +from .molecule import * +from .chain import * +from .model import * +from .options import * XX = 0 diff --git a/pmx/_version.py b/pmx/_version.py index 2ac1af8e..20c791a0 100644 --- a/pmx/_version.py +++ b/pmx/_version.py @@ -86,20 +86,20 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, if e.errno == errno.ENOENT: continue if verbose: - print("unable to run %s" % dispcmd) + print(("unable to run %s" % dispcmd)) print(e) return None, None else: if verbose: - print("unable to find command, tried %s" % (commands,)) + print(("unable to find command, tried %s" % (commands,))) return None, None stdout = p.communicate()[0].strip() if sys.version_info[0] >= 3: stdout = stdout.decode() if p.returncode != 0: if verbose: - print("unable to run %s (error)" % dispcmd) - print("stdout was %s" % stdout) + print(("unable to run %s (error)" % dispcmd)) + print(("stdout was %s" % stdout)) return None, p.returncode return stdout, p.returncode @@ -124,8 +124,8 @@ def versions_from_parentdir(parentdir_prefix, root, verbose): root = os.path.dirname(root) # up a level if verbose: - print("Tried directories %s but none started with prefix %s" % - (str(rootdirs), parentdir_prefix)) + print(("Tried directories %s but none started with prefix %s" % + (str(rootdirs), parentdir_prefix))) raise NotThisMethod("rootdir doesn't start with parentdir_prefix") @@ -192,15 +192,15 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): # "stabilization", as well as "HEAD" and "master". tags = set([r for r in refs if re.search(r'\d', r)]) if verbose: - print("discarding '%s', no digits" % ",".join(refs - tags)) + print(("discarding '%s', no digits" % ",".join(refs - tags))) if verbose: - print("likely tags: %s" % ",".join(sorted(tags))) + print(("likely tags: %s" % ",".join(sorted(tags)))) for ref in sorted(tags): # sorting will prefer e.g. "2.0" over "2.0rc1" if ref.startswith(tag_prefix): r = ref[len(tag_prefix):] if verbose: - print("picking %s" % r) + print(("picking %s" % r)) return {"version": r, "full-revisionid": keywords["full"].strip(), "dirty": False, "error": None, @@ -229,7 +229,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): hide_stderr=True) if rc != 0: if verbose: - print("Directory %s not under git control" % root) + print(("Directory %s not under git control" % root)) raise NotThisMethod("'git rev-parse --git-dir' returned error") # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] @@ -278,7 +278,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): if not full_tag.startswith(tag_prefix): if verbose: fmt = "tag '%s' doesn't start with prefix '%s'" - print(fmt % (full_tag, tag_prefix)) + print((fmt % (full_tag, tag_prefix))) pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" % (full_tag, tag_prefix)) return pieces diff --git a/pmx/atom.py b/pmx/atom.py index f3805871..c8179506 100644 --- a/pmx/atom.py +++ b/pmx/atom.py @@ -45,14 +45,15 @@ - output >>> print atom # prints atom in pdb format - + """ -import _pmx as _p +from . import _pmx as _p from numpy import * -import copy, library -from library import pdb_format, pdb_format2 +import copy +from . import library +from .library import pdb_format, pdb_format2 class Atom: """ class for storage of atom properties and methods""" @@ -100,13 +101,13 @@ def __init__(self, line = None, mol2line = None, **kwargs): self.ptype = '' self.long_name = '' self.unity='A' - for key, val in kwargs.items(): + for key, val in list(kwargs.items()): setattr(self,key,val) if line is not None: self.readPDBString(line) if mol2line is not None: self.read_mol2_line(mol2line) - + def readPDBString(self,line,origID=0): """PDB String to Atom""" @@ -122,7 +123,7 @@ def readPDBString(self,line,origID=0): except: self.resnr=line[22:27] # contains insertion code # self.resnr=int(line[22:27][:-1]) - + self.x=[float(line[30:38]),\ float(line[39:46]),float(line[47:54])] try: @@ -179,14 +180,14 @@ def a2nm(self): self.x[1]*=.1 self.x[2]*=.1 self.unity = 'nm' - + def angle(self,other1,other2,degree=None): """ Calcluates the angle between 3 atoms Usage: atom1.angle(atom2,atom3) The degree flag causes the function to return the angle in degrees. (Note: atom1 must be between 2 and 3)""" - + angle= _p.angle(other1.x,self.x,other2.x) if degree: return angle*180.0/pi @@ -199,7 +200,7 @@ def dihedral(self,other1,other2,other3,degree=None): Usage: atom1.dihedral(atom2,atom3,atom4) The degree flag causes the function to return the dihedral in degrees.""" - + ang=_p.dihedral(self.x,other1.x,other2.x,other3.x) if degree: return ang*180.0/pi @@ -209,7 +210,7 @@ def dihedral(self,other1,other2,other3,degree=None): def __str__(self): """ prints the atom in PDB format """ if self.unity=='nm': - coords = map(lambda x: x*10, self.x) + coords = [x*10 for x in self.x] else: coords = self.x if len(self.resname)<4: @@ -263,8 +264,8 @@ def make_long_name(self): and order""" # check for aliases first ali = library._aliases - if ali.has_key(self.resname) and \ - ali[self.resname].has_key(self.name): + if self.resname in ali and \ + self.name in ali[self.resname]: name = ali[self.resname][self.name] else: name = self.name.strip() @@ -333,7 +334,7 @@ def get_symbol(self): else: self.symbol = 'UN' ## print 'Using symbol %s for atom %s-%s' %\ -## (self.symbol,self.name,self.resname) +## (self.symbol,self.name,self.resname) def get_order(self): """ get the order (number of bonds to mainchain)""" if self.long_name == '': @@ -341,9 +342,9 @@ def get_order(self): if self.symbol == '': self.get_symbol() if self.resname not in library._protein_residues: - print 'Sorry, implemented for proteins only' + print('Sorry, implemented for proteins only') return - + el = self.symbol x = self.long_name[2] if self.name in ['C','CA','N']: self.order = 0 @@ -352,7 +353,7 @@ def get_order(self): 'O2','OC1','OC2','OXT', 'OT1','OT2']: self.order = 1 - else: + else: if el!='H': if x=='B': self.order = 1 elif x=='G': self.order = 2 @@ -396,10 +397,7 @@ def read_mol2_line(self,line): self.unity = 'A' self.symbol = self.atype.split('.')[0] else: - print 'Error: Cannot convert line to atom' - print line + print('Error: Cannot convert line to atom') + print(line) sys.exit(1) return self - - - diff --git a/pmx/atomselection.py b/pmx/atomselection.py index 315c1f4d..44a99251 100644 --- a/pmx/atomselection.py +++ b/pmx/atomselection.py @@ -37,11 +37,11 @@ import sys from numpy import * import random -from atom import * -from geometry import Rotation -import library +from .atom import * +from .geometry import Rotation +from . import library import copy as cp -import _pmx +from . import _pmx #import _gridns XX = 0 @@ -52,17 +52,17 @@ class Atomselection: """ Basic class to handle sets of atoms. Atoms are stored in a list """ - + def __init__(self, **kwargs): self.atoms = [] self.unity = 'A' - for key, val in kwargs.items(): + for key, val in list(kwargs.items()): setattr(self,key,val) def writePDB(self,fname,title="",nr=1,bPDBTER=False,bAssignChainIDs=False,resnrlist=[]): - if nr > 1: - fp = open(fname,'a') - else: + if nr > 1: + fp = open(fname,'a') + else: fp = open(fname,'w') if not title: if hasattr(self,"title"): @@ -71,33 +71,33 @@ def writePDB(self,fname,title="",nr=1,bPDBTER=False,bAssignChainIDs=False,resnrl title = str(self.__class__)+' '+str(self) header = 'TITLE '+title - print >>fp, header - print >>fp, 'MODEL%5d' % nr + print(header, file=fp) + print('MODEL%5d' % nr, file=fp) if not hasattr(self,"box"): self.box = [ [0,0,0], [0,0,0], [0,0,0] ] if self.box[XX][XX]*self.box[YY][YY]*self.box[ZZ][ZZ] != 0: box_line = _pmx.box_as_cryst1( self.box ) - print >>fp, box_line + print(box_line, file=fp) - chainID = self.atoms[0].chain_id + chainID = self.atoms[0].chain_id for atom in self.atoms: - if (bPDBTER==True) and (atom.chain_id != chainID): - print >>fp, 'TER' - chainID = atom.chain_id - if (len(resnrlist)>0) and (atom.resnr not in resnrlist): - continue - if atom.chain_id.startswith('pmx'): + if (bPDBTER==True) and (atom.chain_id != chainID): + print('TER', file=fp) + chainID = atom.chain_id + if (len(resnrlist)>0) and (atom.resnr not in resnrlist): + continue + if atom.chain_id.startswith('pmx'): if bAssignChainIDs==False: - atom.chain_id = "" + atom.chain_id = "" else: atom.chain_id = atom.chain_id#[-1] if( len(atom.name) > 4): # too long atom name foo = cp.deepcopy(atom) foo.name = foo.name[:4] - print >>fp, foo + print(foo, file=fp) else: - print >>fp, atom - print >>fp, 'ENDMDL' + print(atom, file=fp) + print('ENDMDL', file=fp) fp.close() @@ -110,8 +110,8 @@ def writeGRO( self, filename, title = ''): title = self.title else: title = str(self.__class__)+' '+str(self) - print >>fp, title - print >>fp, "%5d" % len(self.atoms) + print(title, file=fp) + print("%5d" % len(self.atoms), file=fp) if self.atoms[0].v[0] != 0.000 : bVel = True else: bVel = False if bVel: @@ -127,7 +127,7 @@ def writeGRO( self, filename, title = ''): atom.v[XX], atom.v[YY], atom.v[ZZ]) else: ff+=gro_format % (atom.x[XX]*fac, atom.x[YY]*fac, atom.x[ZZ]*fac ) - print >>fp, ff + print(ff, file=fp) if not hasattr(self,"box"): self.box = [ [0,0,0], [0,0,0], [0,0,0] ] @@ -139,11 +139,11 @@ def writeGRO( self, filename, title = ''): bTric = True ff = "%10.5f%10.5f%10.5f" if bTric: - print >>fp, ff % (self.box[XX][XX],self.box[YY][YY],self.box[ZZ][ZZ]) + print(ff % (self.box[XX][XX],self.box[YY][YY],self.box[ZZ][ZZ]), file=fp) else: - print >>fp, ff % (self.box[XX][XX],self.box[YY][YY],self.box[ZZ][ZZ], + print(ff % (self.box[XX][XX],self.box[YY][YY],self.box[ZZ][ZZ], self.box[XX][YY],self.box[XX][ZZ],self.box[YY][XX], - self.box[YY][ZZ],self.box[ZZ][XX],self.box[ZZ][YY]) + self.box[YY][ZZ],self.box[ZZ][XX],self.box[ZZ][YY]), file=fp) fp.close() def write(self,fn, title = '', nr = 1): @@ -153,21 +153,21 @@ def write(self,fn, title = '', nr = 1): elif ext == 'gro': self.writeGRO( fn, title ) else: - print >>sys.stderr, 'pmx_Error_> Can only write pdb or gro!' + print('pmx_Error_> Can only write pdb or gro!', file=sys.stderr) sys.exit(1) - + def com(self,vector_only=False): """move atoms to center of mass or return vector only""" for atom in self.atoms: if atom.m == 0: - print >>sys.stderr, " Warning: Atom has zero mass: setting mass to 1." + print(" Warning: Atom has zero mass: setting mass to 1.", file=sys.stderr) atom.m = 1. - x = sum(map(lambda a: a.x[0]*a.m, self.atoms)) - y = sum(map(lambda a: a.x[1]*a.m, self.atoms)) - z = sum(map(lambda a: a.x[2]*a.m, self.atoms)) - M = sum(map(lambda a: a.m, self.atoms)) + x = sum([a.x[0]*a.m for a in self.atoms]) + y = sum([a.x[1]*a.m for a in self.atoms]) + z = sum([a.x[2]*a.m for a in self.atoms]) + M = sum([a.m for a in self.atoms]) x/=M y/=M z/=M @@ -178,14 +178,14 @@ def com(self,vector_only=False): atom.x[0]-=x atom.x[1]-=y atom.x[2]-=z - + def atomlistFromTop(self,topDic): """ return a list of atom objects found in topDic""" self.atoms=[] - for idx in topDic['atoms'].keys(): + for idx in list(topDic['atoms'].keys()): at=Atom().atomFromTop(topDic,idx) self.atoms.append(at) return self @@ -205,7 +205,7 @@ def a2nm(self): atom.x[2]*=.1 atom.unity = 'nm' self.unity = 'nm' - + def nm2a(self): if self.unity == 'A': return @@ -215,11 +215,11 @@ def nm2a(self): atom.x[2]*=10. atom.unity = 'A' self.unity = 'A' - + def get_long_name(self): for atom in self.atoms: atom.make_long_name() - + def get_symbol(self): for atom in self.atoms: atom.get_symbol() @@ -230,9 +230,9 @@ def get_order(self): def max_crd(self): - x = map(lambda a: a.x[0], self.atoms) - y = map(lambda a: a.x[1], self.atoms) - z = map(lambda a: a.x[2], self.atoms) + x = [a.x[0] for a in self.atoms] + y = [a.x[1] for a in self.atoms] + z = [a.x[2] for a in self.atoms] return (min(x),max(x)),(min(y),max(y)),(min(z),max(z)) def search_neighbors(self, cutoff = 8., build_bonds = True ): @@ -241,11 +241,11 @@ def search_neighbors(self, cutoff = 8., build_bonds = True ): changed = True self.nm2a() _pmx.search_neighbors(self.atoms, cutoff, build_bonds ) - - + + def coords(self): - return map(lambda a: a.x, self.atoms) + return [a.x for a in self.atoms] def fetch_atoms(self,key,how='byname',wildcard=False,inv=False): @@ -305,7 +305,7 @@ def translate(self, vec): atom.x[0]+=vec[0] atom.x[1]+=vec[1] atom.x[2]+=vec[2] - + def random_rotation(self): vec = self.com(vector_only = True) @@ -343,16 +343,12 @@ def make_mol2_bondlist(self): newl.append((at1,at2,tp)) check = True if not check: - print 'bondtype %s-%s defaults to 1' % (at1.atype, at2.atype) + print('bondtype %s-%s defaults to 1' % (at1.atype, at2.atype)) newl.append((at1,at2,'1')) self.bondlist = newl - + def get_by_id(self, lst): atlst = [] for idx in lst: atlst.append(self.atoms[idx-1]) return atlst - - - - diff --git a/pmx/builder.py b/pmx/builder.py index 9ff09cb5..03159bce 100644 --- a/pmx/builder.py +++ b/pmx/builder.py @@ -42,14 +42,14 @@ >>> ch = build_chain('FGHRTCV',ss='HHHHHHH') build as helix >>> ch = build_chain('FGHRTCV',dihedrals = ((phi1,psi1,omega1),(...))) build chain with defined dihedral angles - + """ import sys, os -from library import pmx_data_file -from geometry import * -from chain import * -from atom import Atom -from model import Model +from .library import pmx_data_file +from .geometry import * +from .chain import * +from .atom import Atom +from .model import Model def cross(x,y): @@ -61,12 +61,12 @@ def cross(x,y): -x[1]*y[0]]) - + def add_bp(m, strand = None, bRNA=False): if strand: - N = len(strand)/2 - if bRNA: - N = len(strand) + N = len(strand)/2 + if bRNA: + N = len(strand) else: N = 1 # print N, len(strand) @@ -180,8 +180,8 @@ def build_rna_strand(seq): def get_fragments(): dic = pmx_data_file('fragments.pkl') - n = len(dic.keys()) - print >>sys.stderr,"pmx__> # Fragments loaded: %d" % n + n = len(list(dic.keys())) + print("pmx__> # Fragments loaded: %d" % n, file=sys.stderr) return dic @@ -207,19 +207,19 @@ def write_pdb_with_connect(mol, f, n = 1): fp = open(f,"w") else: fp = f - print >>fp, "MODEL%5d" % n + print("MODEL%5d" % n, file=fp) for atom in mol.atoms: - print >>fp, atom + print(atom, file=fp) for atom in mol.atoms: s= "CONECT%5d" % atom.id for a in atom.bonds: s+='%5d' % a.id - print >>fp, s + print(s, file=fp) def attach_group(atom, mol): master = atom.molecule - + bb = atom.bonds[0] R = mol.fetch_atoms('R#')[0] bR = R.bonds[0] @@ -264,8 +264,8 @@ def make_residue(key,hydrogens = True): """ returns a molecule object with default geometry""" - if not library._aacids.has_key(key): - raise KeyError, "Residue %s not known" % key + if key not in library._aacids: + raise KeyError("Residue %s not known" % key) m = Molecule() m.unity = 'A' m.resname = key @@ -454,5 +454,3 @@ def attach_aminoacid(mol, resname, hydrogens = True, set_psi(new,psi) return new - - diff --git a/pmx/chain.py b/pmx/chain.py index 1f7e7d78..d8653f88 100644 --- a/pmx/chain.py +++ b/pmx/chain.py @@ -39,7 +39,7 @@ - ch.atoms -> list of atoms . . - + Some methods: >>> ch.get_sequence() # return sequence in one-letter code >>> first_res = ch.residues[0].copy() # copy first residue @@ -47,11 +47,12 @@ >>> ch.insert(5,first_res) # insert residue at position 5 . . - + """ -from atomselection import * -from molecule import * -import copy, library +from .atomselection import * +from .molecule import * +import copy +from . import library #import builder class Chain(Atomselection): @@ -63,13 +64,13 @@ def __init__(self, seq = None, **kwargs): self.model = None self.nres = 0 self.id = '' - for key, val in kwargs.items(): + for key, val in list(kwargs.items()): setattr(self,key,val) if self.residues: self.al_from_resl() if seq: self.create( seq ) - + def __str__(self): s = '< Chain: id = %s nres = %d natoms = %d >' % \ (self.id, len(self.residues), len(self.atoms)) @@ -79,7 +80,7 @@ def __delitem__(self,item): res = self.residues[item] self.remove_residue(res) - + def get_sequence(self): """ returns the sequence as string (for fasta format)""" seq = '' @@ -107,19 +108,19 @@ def al_from_resl(self): for atom in r.atoms: self.atoms.append(atom) atom.chain = self - + def insert_residue(self,pos,mol,newResNum=False): if self.model is not None: have_model = True else: have_model = False - if pos not in range(len(self.residues)+1): - raise ValueError, 'Chain has only %d residues' % \ - len(self.residues) + if pos not in list(range(len(self.residues)+1)): + raise ValueError('Chain has only %d residues' % \ + len(self.residues)) else: mol.set_resid(-999) - if newResNum != False: - mol.set_resid(newResNum) + if newResNum != False: + mol.set_resid(newResNum) mol.set_chain_id(self.id) mol.chain = self if pos == len(self.residues): @@ -134,7 +135,7 @@ def insert_residue(self,pos,mol,newResNum=False): if have_model: self.model.residues.insert(idx_model,mol) self.residues.insert(pos,mol) - if newResNum==False: + if newResNum==False: self.model.renumber_residues() self.model.al_from_resl() self.model.renumber_atoms() @@ -145,12 +146,12 @@ def insert_residue(self,pos,mol,newResNum=False): self.residues.append(mol) else: self.residues.insert(pos,mol) - if newResNum==False: + if newResNum==False: self.renumber_residues() self.al_from_resl() self.renumber_atoms() self.make_residue_tree() - + def renumber_residues(self): for i, res in enumerate(self.residues): res.set_resid(i+1) @@ -166,9 +167,9 @@ def insert_chain(self,pos,chain): resl = chain.residues else: resl = chain - if pos not in range(len(self.residues)+1): - raise ValueError, 'Chain has only %d residues' % \ - len(self.residues) + if pos not in list(range(len(self.residues)+1)): + raise ValueError('Chain has only %d residues' % \ + len(self.residues)) if pos == len(self.residues): m = self.residues[-1] if have_model: @@ -177,7 +178,7 @@ def insert_chain(self,pos,chain): m = self.residues[pos] if have_model: idx_model = self.model.residues.index(m) - + first = self.residues[:pos] last = self.residues[pos:] for res in resl: @@ -222,22 +223,22 @@ def remove_residue(self,residue,bKeepResNum=False): self.atoms.append(atom) if midx!=-1: self.model.renumber_atoms() - if bKeepResNum==False: + if bKeepResNum==False: self.model.renumber_residues() self.make_residue_tree() - + def replace_residue(self,residue, new, bKeepResNum=False): idx = self.residues.index(residue) - if bKeepResNum==True: + if bKeepResNum==True: self.insert_residue(idx,new,residue.id) - else: - self.insert_residue(idx,new) + else: + self.insert_residue(idx,new) self.remove_residue(residue,bKeepResNum) def remove_atom(self,atom): m = atom.molecule m.remove_atom(atom) - + def fetch_residues(self,key, inv=False): if not hasattr(key,"append"): key = [key] @@ -251,7 +252,7 @@ def fetch_residues(self,key, inv=False): if r.resname not in key: result.append(r) return result - + def set_chain_id(self,chain_id): old_id = self.id self.id = chain_id @@ -260,11 +261,11 @@ def set_chain_id(self,chain_id): if self.model: self.model.chdic[chain_id] = self del self.model.chdic[old_id] - + def append(self,mol): if not isinstance(mol,Molecule): - raise TypeError, "%s is not a Molecule instance" % str(mol) + raise TypeError("%s is not a Molecule instance" % str(mol)) else: n = len(self.residues) self.insert_residue(n,mol) @@ -284,8 +285,8 @@ def get_bonded(self): if self.unity=='A': d*=.1 if d > 0.45: - print 'Warning: Long Bond %d-%s <-> %d-%s' %\ - (r.id,r.resname,r2.id,r2.resname) + print('Warning: Long Bond %d-%s <-> %d-%s' %\ + (r.id,r.resname,r2.id,r2.resname)) else: c.bonds.append(n) n.bonds.append(c) @@ -308,7 +309,7 @@ def get_mol2_resname(self): elif r.resname == 'GLU': r.mol2_resname = 'glu-' elif r.resname == 'ASP': r.mol2_resname = 'asp-' else: r.mol2_resname = r.resname.lower() - + def add_nterm_cap(self): if self.unity =='nm': @@ -327,7 +328,7 @@ def add_nterm_cap(self): vec = array(ca.x)-array(n.x) x = 1./linalg.norm(vec) n.x = array(ca.x)-vec*x - m.set_resname('ACE') + m.set_resname('ACE') if changed: self.a2nm() @@ -361,8 +362,8 @@ def add_cterm_cap(self): m.set_resname('NME') if changed: self.a2nm() - - + + def attach_chain(self, newchain, phi = -139., psi = 135.): if self.unity =='nm': self.nm2a() @@ -375,7 +376,7 @@ def attach_chain(self, newchain, phi = -139., psi = 135.): self.insert_chain(len(self.residues), ch) if changed: self.a2nm() - + def __prepare_nterm_for_extension(self): nterm = self.nterminus() @@ -393,7 +394,7 @@ def __prepare_nterm_for_extension(self): except: h1 = nterm.fetch('HN')[0] # will become H h1.name = 'H' - + else: try: del nterm['H1'] @@ -417,11 +418,11 @@ def __prepare_nterm_for_extension(self): del nterm['H3'] except: pass - + def __prepare_cterm_for_extension(self): cterm = self.cterminus() if cterm.resname not in library._protein_residues: - print " Cannot attach to this residue! ", cterm.resname + print(" Cannot attach to this residue! ", cterm.resname) sys.exit(1) a = cterm.fetch_atoms('OXT') if a: @@ -438,7 +439,7 @@ def __prepare_cterm_for_extension(self): a = cterm.fetch_atoms('O\'') if a: a[0].name = 'O' - + def cbuild(self, resn, next_phi = -139., psi = 135.): if len(resn) == 1: @@ -490,38 +491,38 @@ def cbuild(self, resn, next_phi = -139., psi = 135.): for atom in new.atoms: atom.x = r.apply(atom.x,pi/3.) - + # do next rotation # here we correct the C-N-Ca angle # special correction for proline if new.resname == 'PRO': - N, CA2,H = new.fetchm(['N','CA','CD']) - Ca, C, O, Nn = cterm.fetchm(['CA','C','O','N']) - v1 = array(N.x)-array(CA2.x) - v2 = array(H.x)-array(N.x) - cr = cross(v1,v2) - x = 1./linalg.norm(cr) - cr = cr*x - v3 = array(Ca.x)-array(C.x) - v4 = array(C.x)-array(O.x) - cr2 = cross(v3,v4) - x = 1./linalg.norm(cr2) - cr2 = cr2*x - d = dot(cr,cr2) - dd = arccos(dot(cr,cr2)) - v5 = cross(cr,cr2) - x = 1./linalg.norm(v5) - v5 = v5*x - rv = N.x + v5 - r = Rotation(rv,N.x) - for atom in new.atoms: - if atom.name !='N': - atom.x = r.apply(atom.x,-dd) - - - + N, CA2,H = new.fetchm(['N','CA','CD']) + Ca, C, O, Nn = cterm.fetchm(['CA','C','O','N']) + v1 = array(N.x)-array(CA2.x) + v2 = array(H.x)-array(N.x) + cr = cross(v1,v2) + x = 1./linalg.norm(cr) + cr = cr*x + v3 = array(Ca.x)-array(C.x) + v4 = array(C.x)-array(O.x) + cr2 = cross(v3,v4) + x = 1./linalg.norm(cr2) + cr2 = cr2*x + d = dot(cr,cr2) + dd = arccos(dot(cr,cr2)) + v5 = cross(cr,cr2) + x = 1./linalg.norm(v5) + v5 = v5*x + rv = N.x + v5 + r = Rotation(rv,N.x) + for atom in new.atoms: + if atom.name !='N': + atom.x = r.apply(atom.x,-dd) + + + Ca, C, O = cterm.fetchm(['CA','C','O']) N, CA2 = new.fetchm(['N','CA']) v1 = array(N.x)-array(C.x) @@ -541,7 +542,7 @@ def cbuild(self, resn, next_phi = -139., psi = 135.): atom.x = r.apply(atom.x,-delta) an = N.angle(C,CA2) - + if new.resname == 'PRO': CD = new.fetch('CD')[0] aa = N.angle(CD,C, degree=True) @@ -570,14 +571,14 @@ def cbuild(self, resn, next_phi = -139., psi = 135.): self.a2nm() - - def nbuild(self, resn, phi = -139., psi = 135.): + + def nbuild(self, resn, phi = -139., psi = 135.): if len(resn) == 1: resn = library._aacids_dic[resn] # new = builder.make_residue(resn,hydrogens = True) new = Molecule().new_aa(resn) - + # we need Ca, C and O from nterm Ca, C, O, Nn = new.fetchm(['CA','C','O','N']) # and N from new @@ -599,18 +600,18 @@ def nbuild(self, resn, phi = -139., psi = 135.): vec = v*x*l newpos = array(N.x)+vec t = array(C.x)-newpos - + # shift to new position for a in new.atoms: a.x = array(a.x)-t # get Ca,C,O and N,H,CA2 in plane - + v1 = array(N.x)-array(CA2.x) v2 = array(H.x)-array(N.x) cr = cross(v1,v2) x = 1./linalg.norm(cr) cr = cr*x - + v3 = array(Ca.x)-array(C.x) v4 = array(C.x)-array(O.x) cr2 = cross(v3,v4) @@ -652,13 +653,13 @@ def nbuild(self, resn, phi = -139., psi = 135.): for atom in new.atoms: if atom.name !='C': atom.x = r.apply(atom.x,dd) - dih = CA2.dihedral(N,C,Ca) + dih = CA2.dihedral(N,C,Ca) delta = pi-dih r = Rotation(N.x,C.x) for atom in new.atoms: if atom.name !='C': atom.x = r.apply(atom.x,delta) - ang = Nn.dihedral(Ca,C,N) + ang = Nn.dihedral(Ca,C,N) dd = pi - ang r = Rotation(C.x,Ca.x) for atom in new.atoms: @@ -666,7 +667,7 @@ def nbuild(self, resn, phi = -139., psi = 135.): atom.x = r.apply(atom.x,dd) - dih = H.dihedral(N,C,O) + dih = H.dihedral(N,C,O) delta = pi-dih r = Rotation(N.x,C.x) O.x = r.apply(O.x,delta) @@ -688,7 +689,7 @@ def create(self, seq, phi_psi = [], ss = []): ## phi_psi.append( [-57,-47] ) ## elif ss[i] == 'E': ## phi_psi.append( [-139, 135] ) - + ## if not phi_psi: ## print seq, len(seq) ## for i in range(len(seq)): @@ -702,7 +703,7 @@ def create(self, seq, phi_psi = [], ss = []): resn = library._aacids_dic[first_res] # new = builder.make_residue(resn,hydrogens = True) new = Molecule().new_aa(resn) - + self.residues.append( new ) new.chain = self ## new.set_phi( phi_psi[0][0] ) @@ -712,7 +713,7 @@ def create(self, seq, phi_psi = [], ss = []): for i, aa in enumerate(seq[1:]): self.cbuild(aa) #, phi_psi[i+1][0], phi_psi[i+1][1]) return self - + def fuse(self, new, phi=-139, psi=135 ): if new.unity != 'A': newchain.nm2a() @@ -755,28 +756,28 @@ def fuse(self, new, phi=-139, psi=135 ): # special correction for proline if nterm.resname == 'PRO': - N, CA2,H = nterm.fetchm(['N','CA','CD']) - Ca, C, O, Nn = cterm.fetchm(['CA','C','O','N']) - v1 = array(N.x)-array(CA2.x) - v2 = array(H.x)-array(N.x) - cr = cross(v1,v2) - x = 1./linalg.norm(cr) - cr = cr*x - v3 = array(Ca.x)-array(C.x) - v4 = array(C.x)-array(O.x) - cr2 = cross(v3,v4) - x = 1./linalg.norm(cr2) - cr2 = cr2*x - d = dot(cr,cr2) - dd = arccos(dot(cr,cr2)) - v5 = cross(cr,cr2) - x = 1./linalg.norm(v5) - v5 = v5*x - rv = N.x + v5 - r = Rotation(rv,N.x) - for atom in new.atoms: - if atom.name !='N' or atom.molecule != nterm: - atom.x = r.apply(atom.x,-dd) + N, CA2,H = nterm.fetchm(['N','CA','CD']) + Ca, C, O, Nn = cterm.fetchm(['CA','C','O','N']) + v1 = array(N.x)-array(CA2.x) + v2 = array(H.x)-array(N.x) + cr = cross(v1,v2) + x = 1./linalg.norm(cr) + cr = cr*x + v3 = array(Ca.x)-array(C.x) + v4 = array(C.x)-array(O.x) + cr2 = cross(v3,v4) + x = 1./linalg.norm(cr2) + cr2 = cr2*x + d = dot(cr,cr2) + dd = arccos(dot(cr,cr2)) + v5 = cross(cr,cr2) + x = 1./linalg.norm(v5) + v5 = v5*x + rv = N.x + v5 + r = Rotation(rv,N.x) + for atom in new.atoms: + if atom.name !='N' or atom.molecule != nterm: + atom.x = r.apply(atom.x,-dd) Ca, C, O = cterm.fetchm(['CA','C','O']) N, CA2 = nterm.fetchm(['N','CA']) @@ -839,9 +840,9 @@ def make_residue_tree(self): r.next = next_res next_res.previous = r else: - print >>sys.stderr, 'Gap between residues ', r, '< - >', next_res, 'dist = ', d + print('Gap between residues ', r, '< - >', next_res, 'dist = ', d, file=sys.stderr) self.residue_tree_ok = False - + def cterminus(self): i = len(self.residues) - 1 r = self.residues[i] @@ -861,7 +862,7 @@ def nterminus(self): r = self.residues[i] if r.is_protein_residue(): return r return None - + def rename_atoms(self): for atom in self.atoms: atom.make_long_name() @@ -878,6 +879,3 @@ def rename_atoms(self): def residue(self, idx): return self.residues[idx-1] - - - diff --git a/pmx/cpp.py b/pmx/cpp.py index 7ff6e7b2..c8e3ebed 100644 --- a/pmx/cpp.py +++ b/pmx/cpp.py @@ -34,7 +34,6 @@ import os import re -import string # # First "subsystem" of regular expressions that we set up: @@ -76,7 +75,7 @@ # the corresponding compiled regular expression that fetches the arguments # we care about. Table = {} -for op_list, expr in cpp_lines_dict.items(): +for op_list, expr in list(cpp_lines_dict.items()): e = re.compile(expr) for op in op_list: Table[op] = e @@ -91,7 +90,7 @@ override = { 'if' : 'if(?!def)', } -l = map(lambda x, o=override: o.get(x, x), Table.keys()) +l = list(map(lambda x, o=override: o.get(x, x), list(Table.keys()))) # Turn the list of expressions into one big honkin' regular expression @@ -99,7 +98,7 @@ # a list of tuples, one for each preprocessor line. The preprocessor # directive will be the first element in each tuple, and the rest of # the line will be the second element. -e = '^\s*#\s*(' + string.join(l, '|') + ')(.*)$' +e = '^\s*#\s*(' + '|'.join(l) + ')(.*)$' # And last but not least, compile the expression. CPP_Expression = re.compile(e, re.M) @@ -134,12 +133,12 @@ # re module, as late as version 2.2.2, empirically matches the # "!" in "!=" first, instead of finding the longest match. # What's up with that? -l = CPP_to_Python_Ops_Dict.keys() -l.sort(lambda a, b: cmp(len(b), len(a))) +l = list(CPP_to_Python_Ops_Dict.keys()) +l.sort(key=len, reverse=True) # Turn the list of keys into one regular expression that will allow us # to substitute all of the operators at once. -expr = string.join(map(re.escape, l), '|') +expr = '|'.join(list(map(re.escape, l))) # ...and compile the expression. CPP_to_Python_Ops_Expression = re.compile(expr) @@ -192,7 +191,7 @@ def __init__(self, name, args, expansion): self.name = name self.args = function_arg_separator.split(args) try: - expansion = string.split(expansion, '##') + expansion = expansion.split('##') except (AttributeError, TypeError): # Python 1.5 throws TypeError if "expansion" isn't a string, # later versions throw AttributeError. @@ -204,7 +203,7 @@ def __call__(self, *values): with the specified values. """ if len(self.args) != len(values): - raise ValueError, "Incorrect number of arguments to `%s'" % self.name + raise ValueError("Incorrect number of arguments to `%s'" % self.name) # Create a dictionary that maps the macro arguments to the # corresponding values in this "call." We'll use this when we # eval() the expansion so that arguments will get expanded to @@ -218,7 +217,7 @@ def __call__(self, *values): if not s in self.args: s = repr(s) parts.append(s) - statement = string.join(parts, ' + ') + statement = ' + '.join(parts) return eval(statement, globals(), locals) @@ -261,7 +260,7 @@ def __init__(self, current=os.curdir, cpppath=(), dict={}, all=0): self.cpp_namespace['__dict__'] = self.cpp_namespace if all: - self.do_include = self.all_include + self.do_include = self.all_include # For efficiency, a dispatch table maps each C preprocessor # directive (#if, #define, etc.) to the method that should be @@ -273,7 +272,7 @@ def __init__(self, current=os.curdir, cpppath=(), dict={}, all=0): d = { 'scons_current_file' : self.scons_current_file } - for op in Table.keys(): + for op in list(Table.keys()): d[op] = getattr(self, 'do_' + op) self.default_table = d @@ -292,9 +291,9 @@ def tupleize(self, contents): global CPP_Expression, Table contents = line_continuations.sub('', contents) cpp_tuples = CPP_Expression.findall(contents) - return map(lambda m, t=Table: + return list(map(lambda m, t=Table: (m[0],) + t[m[0]].match(m[1]).groups(), - cpp_tuples) + cpp_tuples)) def __call__(self, file): """ @@ -363,7 +362,7 @@ def eval_expression(self, t): eval()ing it in the C preprocessor namespace we use to track #define values. """ - t = CPP_to_Python(string.join(t[1:])) + t = CPP_to_Python(''.join(t[1:])) try: return eval(t, self.cpp_namespace) except (NameError, TypeError): return 0 @@ -446,13 +445,13 @@ def do_ifdef(self, t): """ Default handling of a #ifdef line. """ - self._do_if_else_condition(self.cpp_namespace.has_key(t[1])) + self._do_if_else_condition(t[1] in self.cpp_namespace) def do_ifndef(self, t): """ Default handling of a #ifndef line. """ - self._do_if_else_condition(not self.cpp_namespace.has_key(t[1])) + self._do_if_else_condition(t[1] not in self.cpp_namespace) def do_if(self, t): """ @@ -563,7 +562,7 @@ def resolve_include(self, t): s = self.cpp_namespace[m.group(1)] if callable(s): args = function_arg_separator.split(m.group(2)) - s = apply(s, args) + s = s(*args) if not s: return None return (t[0], s[0], s[1:-1]) @@ -584,11 +583,9 @@ class DumbPreProcessor(PreProcessor): to tailor its behavior. """ def __init__(self, *args, **kw): - apply(PreProcessor.__init__, (self,)+args, kw) + PreProcessor.__init__(*(self,)+args, **kw) d = self.default_table for func in ['if', 'elif', 'else', 'endif', 'ifdef', 'ifndef']: d[func] = d[func] = self.do_nothing del __revision__ - - diff --git a/pmx/estimators.py b/pmx/estimators.py index 36e57d58..b08773f8 100644 --- a/pmx/estimators.py +++ b/pmx/estimators.py @@ -1,4 +1,4 @@ -from __future__ import print_function, division + import numpy as np import sys from scipy.optimize import fmin @@ -971,7 +971,7 @@ def cdf(dg_data): check = np.sqrt(N)*dmax if not refks: refks = ksref() - lst = filter(lambda x: x[1] > siglev, refks) + lst = [x for x in refks if x[1] > siglev] lam0 = lst[0][0] if check >= lam0: bOk = False diff --git a/pmx/extensions/pmx/Energy.c b/pmx/extensions/pmx/Energy.c index 2ee2114e..82d32ad8 100644 --- a/pmx/extensions/pmx/Energy.c +++ b/pmx/extensions/pmx/Energy.c @@ -284,7 +284,7 @@ PyObject *wrap_calc_improper_energy(PyObject *self, PyObject *args) phi0 = PyFloat_AsDouble( PySequence_GetItem(dihedO, 5) ); kb = PyFloat_AsDouble( PySequence_GetItem(dihedO, 6) ); - mult = PyInt_AsLong( PySequence_GetItem(dihedO, 7) ); + mult = PyLong_AsLong( PySequence_GetItem(dihedO, 7) ); real energy = calc_improper_energy( atom1, atom2, atom3, atom4, kb, phi0, mult); return Py_BuildValue("d",energy); @@ -312,7 +312,7 @@ PyObject *wrap_total_improper_energy(PyObject *self, PyObject *args) PyObject *atom4 = PySequence_GetItem(dihedO,3); phi0 = PyFloat_AsDouble( PySequence_GetItem(dihedO, 5) ); kb = PyFloat_AsDouble( PySequence_GetItem(dihedO, 6) ); - mult = PyInt_AsLong( PySequence_GetItem(dihedO, 7) ); + mult = PyLong_AsLong( PySequence_GetItem(dihedO, 7) ); energy += calc_improper_energy( atom1, atom2, atom3, atom4, kb, phi0, mult); } @@ -331,7 +331,7 @@ real nb_lj_energy( PyObject *atomlist ) int nn = PySequence_Length( nb_list ); for(k=0;k= 3 +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "_pmx", /* m_name */ + "This is a module", /* m_doc */ + -1, /* m_size */ + pmx_methods, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ +}; +PyMODINIT_FUNC PyInit__pmx(void) +{ + PyMODINIT_FUNC m = PyModule_Create(&moduledef); + return m; +} +#else void init_pmx(void) { (void) Py_InitModule3("_pmx",pmx_methods,NULL); } - +#endif \ No newline at end of file diff --git a/pmx/extensions/pmx/wrap_Geometry.c b/pmx/extensions/pmx/wrap_Geometry.c index bb681616..9c939a4b 100644 --- a/pmx/extensions/pmx/wrap_Geometry.c +++ b/pmx/extensions/pmx/wrap_Geometry.c @@ -285,7 +285,7 @@ PyObject *wrap_box_to_cryst1( PyObject *self, PyObject *args) PyObject2matrix(pBox, box); char line[256]; box_to_cryst1(box, line); - return PyString_FromString( line ); + return PyUnicode_FromString( line ); } void Pyvec2rvec( PyObject *Ox, rvec x) @@ -297,7 +297,7 @@ void Pyvec2rvec( PyObject *Ox, rvec x) real get_bond_contribution(PyObject *atom) { - char *elem = PyString_AsString( PyObject_GetAttrString(atom, "symbol") ); + char *elem = PyUnicode_AsEncodedString( PyObject_GetAttrString(atom, "symbol"), "UTF-8", "strict" ); if(strcmp(elem,"C") == 0 ) return CCONTR; else if( strcmp(elem,"H") == 0) return HCONTR; else if( strcmp(elem,"N") == 0) return NCONTR; @@ -317,7 +317,7 @@ void atom_ids_from_py_atomlist( PyObject *list, int *atom_ids) int i; for(i=0;icon[i][size] = id; size++; } for(k=0;kcon[i][size] = id; size++; } for(k=0;kcon[i][size] = id; size++; } @@ -584,7 +584,7 @@ PyObject* wrap_search_neighbors(PyObject *self, PyObject *args) for(i=0;i= len(self.keys): self.__cur_id = 0 raise StopIteration @@ -116,37 +116,37 @@ def write(self, out_file): fp = out_file for key in self.keys: entr = self.entries[key] - print >>fp, '[ %s ]' % key - print >>fp, ' [ atoms ]' + print('[ %s ]' % key, file=fp) + print(' [ atoms ]', file=fp) for atom in entr['atoms']: - print >>fp, "%6s %-15s %8.5f %d" % (atom[0], atom[1], atom[2], atom[3]) + print("%6s %-15s %8.5f %d" % (atom[0], atom[1], atom[2], atom[3]), file=fp) if entr['bonds']: - print >>fp, ' [ bonds ]' + print(' [ bonds ]', file=fp) for bond in entr['bonds']: - print >>fp, "%6s %6s" % (bond[0], bond[1]) + print("%6s %6s" % (bond[0], bond[1]), file=fp) if entr['diheds']: - print >>fp, ' [ dihedrals ]' + print(' [ dihedrals ]', file=fp) for dih in entr['diheds']: - print >>fp, "%6s %6s %6s %6s %-25s" % ( dih[0], dih[1], dih[2], dih[3], dih[4]) + print("%6s %6s %6s %6s %-25s" % ( dih[0], dih[1], dih[2], dih[3], dih[4]), file=fp) if entr['improps']: - print >>fp, ' [ impropers ]' + print(' [ impropers ]', file=fp) for dih in entr['improps']: try: - print >>fp, "%6s %6s %6s %6s %-25s" % ( dih[0], dih[1], dih[2], dih[3], dih[4]) + print("%6s %6s %6s %6s %-25s" % ( dih[0], dih[1], dih[2], dih[3], dih[4]), file=fp) except: - print >>fp, "%6s %6s %6s %6s " % ( dih[0], dih[1], dih[2], dih[3]) - print >>fp + print("%6s %6s %6s %6s " % ( dih[0], dih[1], dih[2], dih[3]), file=fp) + print(file=fp) + - def __check_residue_tree(self, model): for c in model.chains: if not c.residue_tree_ok: - print >>sys.stderr, 'pmx_Error_> Broken residue tree in chain ', c.id + print('pmx_Error_> Broken residue tree in chain ', c.id, file=sys.stderr) sys.exit(1) - + def assign_params( self, model): self.__check_residue_tree(model) self.__assign_atom_params(model) @@ -154,7 +154,7 @@ def assign_params( self, model): self.__make_angles(model) self.__make_dihedrals(model) self.__make_impropers(model) - + def assign_dihedral_params(self, model, directives): for dih in model.dihedral_list: a1, a2, a3, a4 = dih[:4] @@ -181,10 +181,10 @@ def assign_dihedral_params(self, model, directives): name4 = '+'+a4.name d = self.__find_rtp_dihedral(a2.resname, name1, name2, name3, name4 ) if d is not None: - if directives.has_key(d[4]): + if d[4] in directives: dih = dih[:5]+directives[d[4]] else: - print 'No directive found' + print('No directive found') sys.exit(1) def __assign_atom_params(self, model): @@ -196,7 +196,7 @@ def __assign_atom_params(self, model): atom.atomtype = atom_entry[1] atom.q = atom_entry[2] atom.cgnr = atom_entry[3] - + def __make_bonds(self, model): model.bond_list = [] for residue in model.residues: @@ -235,11 +235,11 @@ def __make_bonds(self, model): sg2 = r['SG'] d = sg1 - sg2 if d < 2.5 : - print >> sys.stderr, 'pmx__> Disulfid bond between residue', sg1.resnr, 'and', sg2.resnr + print('pmx__> Disulfid bond between residue', sg1.resnr, 'and', sg2.resnr, file=sys.stderr) sg1.bonds.append(sg2) sg2.bonds.append(sg1) model.bond_list.append( [sg1, sg2] ) - + for atom in model.atoms: for b in atom.bonds: atom.connected.append( b ) @@ -256,7 +256,7 @@ def __make_angles(self, model): atom.connected.append( bb ) bb.connected.append( atom ) model.angle_list.append( [atom, b, bb] ) - + def __make_dihedrals(self, model): model.dihedral_list = [] for atom in model.atoms: @@ -272,8 +272,8 @@ def __make_dihedrals(self, model): bbb.b14.append( atom ) atom.connected.append( bbb ) bbb.connected.append( atom ) - - + + @@ -294,8 +294,8 @@ def __make_impropers(self, model): atoms.append( atom ) assert len(atoms) == 4 model.improper_list.append( atoms+ [imp[4]] ) - - + + def __get_residue_names(self): self.keys = [] for line in self.lines: @@ -303,7 +303,7 @@ def __get_residue_names(self): if line.strip()[1:-1].strip() not in \ ['atoms','bonds','dihedrals','impropers','bondedtypes']: self.keys.append( line.strip()[1:-1].strip() ) - + def __read_residue_entry(self, key ): @@ -321,14 +321,14 @@ def __read_residue_entry(self, key ): else: r.append(line) return r - - + + def __read_rtp_atoms(self, resname, lines ): atoms = [] for line in lines: entr = line.split() - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[0]): + if resname in _aliases : + if entr[0] in _aliases[resname]: entr[0] = _aliases[resname][entr[0]] entr[2] = float(entr[2]) entr[3] = int(entr[3]) @@ -340,12 +340,12 @@ def __read_rtp_bonds(self, resname, lines ): for line in lines: entr = line.split() if entr[0] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[0]): + if resname in _aliases : + if entr[0] in _aliases[resname]: entr[0] = _aliases[resname][entr[0]] if entr[1] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[1]): + if resname in _aliases : + if entr[1] in _aliases[resname]: entr[1] = _aliases[resname][entr[1]] bonds.append(entr) return bonds @@ -355,20 +355,20 @@ def __read_rtp_dihedrals(self, resname, lines ): for line in lines: entr = line.split() if entr[0] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[0]): + if resname in _aliases : + if entr[0] in _aliases[resname]: entr[0] = _aliases[resname][entr[0]] if entr[1] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[1]): + if resname in _aliases : + if entr[1] in _aliases[resname]: entr[1] = _aliases[resname][entr[1]] if entr[2] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[2]): + if resname in _aliases : + if entr[2] in _aliases[resname]: entr[2] = _aliases[resname][entr[2]] if entr[3] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[3]): + if resname in _aliases : + if entr[3] in _aliases[resname]: entr[3] = _aliases[resname][entr[3]] if len(entr) == 5: diheds.append(entr) @@ -381,20 +381,20 @@ def __read_rtp_impropers(self, resname, lines ): for line in lines: entr = line.split() if entr[0] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[0]): + if resname in _aliases : + if entr[0] in _aliases[resname]: entr[0] = _aliases[resname][entr[0]] if entr[1] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[1]): + if resname in _aliases : + if entr[1] in _aliases[resname]: entr[1] = _aliases[resname][entr[1]] if entr[2] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[2]): + if resname in _aliases : + if entr[2] in _aliases[resname]: entr[2] = _aliases[resname][entr[2]] if entr[3] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[3]): + if resname in _aliases : + if entr[3] in _aliases[resname]: entr[3] = _aliases[resname][entr[3]] if len(entr) == 5: improps.append(entr) @@ -430,8 +430,8 @@ def __find_rtp_improper(self, key, name1, name2, name3, name4): d[3] == name1): return d return None - - + + class BondedParser: @@ -446,7 +446,7 @@ def __init__(self, filename = None, version = 'old'): self.dihedraltypes = [] if filename: self.parse(filename) - + def parse(self, filename): if not hasattr(filename,"append"): # not a list filename = pmx_data_file(filename) @@ -464,7 +464,7 @@ def parse(self, filename): def __str__(self): s = '< %s | %s >' % (self.__class__, self.filename ) return s - + def assign_params(self, model): for bond in model.bond_list: params = self.get_bond_param(bond[0].bond_type, bond[1].bond_type) @@ -473,7 +473,7 @@ def assign_params(self, model): params = self.get_angle_param(angle[0].bond_type, angle[1].bond_type, angle[2].bond_type) angle.extend( params ) for dih in model.dihedral_list: - params = self.get_dihedral_param(dih[0].bond_type, dih[1].bond_type, dih[2].bond_type, dih[3].bond_type, 3) + params = self.get_dihedral_param(dih[0].bond_type, dih[1].bond_type, dih[2].bond_type, dih[3].bond_type, 3) dih.extend( params ) for dih in model.improper_list: @@ -484,14 +484,14 @@ def assign_params(self, model): dih = dih[:4] + [1]+ self.directives[dih[4]] - + def get_bond_param(self, type1, type2 ): for entr in self.bondtypes: if (type1 == entr[0] and type2 == entr[1]) or \ (type1 == entr[1] and type2 == entr[0]): return entr[2:] return None - + def get_angle_param(self, type1, type2, type3): for entr in self.angletypes: if (type1 == entr[0] and \ @@ -501,13 +501,13 @@ def get_angle_param(self, type1, type2, type3): type2 == entr[1] and \ type3 == entr[0]): return entr[3:] - return None + return None + - def get_dihedral_param(self, type1,type2,type3,type4,func): - - self.result = [] - found = 0 + + self.result = [] + found = 0 for entr in self.dihedraltypes: if (type1 == entr[0] and \ type2 == entr[1] and \ @@ -517,12 +517,12 @@ def get_dihedral_param(self, type1,type2,type3,type4,func): type2 == entr[2] and \ type3 == entr[1] and \ type4 == entr[0] and func==entr[4]): - self.result.append(entr[4:]) - found = 1 - if(func != 9): - return self.result - if( found==1 ): - return self.result + self.result.append(entr[4:]) + found = 1 + if(func != 9): + return self.result + if( found==1 ): + return self.result for entr in self.dihedraltypes: if ('X' == entr[0] and \ type2 == entr[1] and \ @@ -543,8 +543,8 @@ def get_dihedral_param(self, type1,type2,type3,type4,func): type2 == entr[2] and \ type3 == entr[1] and \ 'X' == entr[0] and func==entr[4]): - self.result.append(entr[4:]) - found = 1 + self.result.append(entr[4:]) + found = 1 if(func != 9): return self.result if( found==1 ): @@ -559,7 +559,7 @@ def get_dihedral_param(self, type1,type2,type3,type4,func): type3 == entr[1] and \ 'X' == entr[0] and func==entr[4]): self.result.append(entr[4:]) - found = 1 + found = 1 if(func != 9): return self.result if( found==1 ): @@ -574,7 +574,7 @@ def get_dihedral_param(self, type1,type2,type3,type4,func): 'X' == entr[1] and \ 'X' == entr[0] and func==entr[4]): self.result.append(entr[4:]) - found = 1 + found = 1 if(func != 9): return self.result if( found==1 ): @@ -591,7 +591,7 @@ def get_dihedral_param(self, type1,type2,type3,type4,func): self.result.append(entr[4:]) if(func != 9): return self.result - for entr in self.dihedraltypes: + for entr in self.dihedraltypes: if (type1 == entr[0] and \ 'X' == entr[1] and \ 'X' == entr[2] and \ @@ -603,7 +603,7 @@ def get_dihedral_param(self, type1,type2,type3,type4,func): self.result.append(entr[4:]) if(func != 9): return self.result - + return self.result @@ -616,7 +616,7 @@ def __parse_directives(self): params = [float(x) for x in entr[2:] ] self.directives[name] = params self.lines = kickOutComments(self.lines,'#') - + def __parse_bondtypes(self): res = [] starts = [] @@ -637,16 +637,16 @@ def __parse_angletypes(self): starts.append(i) for s in starts: lst = readSection(self.lines[s:],'[ angletypes ]','[') - try : + try : lst = parseList('sssiff',lst) except: try: lst = parseList('sssiffff',lst) - except: - print "Unkown Angle type" - exit() + except: + print("Unkown Angle type") + exit() res.extend(lst) - self.angletypes = res + self.angletypes = res def __parse_dihedraltypes(self): res = [] @@ -662,9 +662,9 @@ def __parse_dihedraltypes(self): try: lst = parseList('ssssiffi',lst) except: - try : + try : lst = parseList('ssiffi',lst) - except : + except : lst = parseList('ssssiff',lst) res.extend(lst) self.dihedraltypes = res @@ -682,7 +682,7 @@ def __init__(self, filename = None, version = 'old', ff='amber'): if filename is not None: self.parse(filename, version) - + def parse(self, filename, version): if not hasattr(filename,"append"): # not a list filename = pmx_data_file(filename) @@ -697,12 +697,12 @@ def parse(self, filename, version): def __str__(self): s = '< %s | %s >' % (self.__class__, self.filename ) return s - + def __parse_atomtypes(self, version): self.atomtypes = {} lst = readSection(self.lines,'[ atomtypes ]','[') - ffnamelower = self.ff.lower() + ffnamelower = self.ff.lower() if version == 'old': if ffnamelower.startswith('amber') : lst = parseList('ssffsff',lst) @@ -722,7 +722,7 @@ def __parse_atomtypes(self, version): 'sigma':entr[6]*10, # nm -> A 'eps':entr[7] } - + elif version == 'new': if ffnamelower.startswith('amber') or ffnamelower.startswith('charmm'): lst = parseList('siffsff',lst) @@ -741,7 +741,7 @@ def __parse_atomtypes(self, version): 'mass':float(entr[3]), 'sigma':entr[6]*10, # nm -> A 'eps':entr[7] - } + } elif ffnamelower.startswith('gaff'): try: lst = parseList('sffsff',lst) @@ -762,35 +762,32 @@ def __parse_atomtypes(self, version): 'charge':float(entr[3]), 'sigma':entr[5]*10, # nm -> A 'eps':entr[6] - } - + } + def assign_params(self, model): for atom in model.atoms: atom.bond_type = self.atomtypes[atom.atomtype]['bond_type'] atom.sigma = self.atomtypes[atom.atomtype]['sigma'] atom.eps = self.atomtypes[atom.atomtype]['eps'] - + class ATPParser: - + def __init__(self, fn = 'ffamber99sb.atp'): self.fn = fn self.dic = {} if fn is not None: self.parse() - + def parse(self): lst = open(self.fn).readlines() lst = kickOutComments(lst,';') lst = parseList('sf', lst) for tp, mass in lst: self.dic[tp] = mass - + def __getitem__(self, item): return self.dic[item] - - - diff --git a/pmx/forcefield.py b/pmx/forcefield.py index 6bbc9f94..e73cff8b 100644 --- a/pmx/forcefield.py +++ b/pmx/forcefield.py @@ -31,13 +31,13 @@ Functions to read gromacs forcefield files """ import sys,os,re, copy -from parser import * -import cpp -from atom import Atom -from odict import * -from library import _aliases -from ffparser import * -import _pmx as _p +from .parser import * +from . import cpp +from .atom import Atom +from .odict import * +from .library import _aliases +from .ffparser import * +from . import _pmx as _p def get_bond_param(type1,type2,bond_lib): for entr in bond_lib: @@ -57,7 +57,7 @@ def get_angle_param(type1,type2,type3,ang_lib): type2 == entr[1] and \ type3 == entr[0]): return entr[3:] - return None + return None def get_dihedral_param(type1,type2,type3,type4,dih_lib, func): for entr in dih_lib: @@ -119,7 +119,7 @@ def get_dihedral_param(type1,type2,type3,type4,dih_lib, func): 'X' == entr[1] and \ type4 == entr[0] and func==entr[4]): return entr[4:] - return None + return None @@ -143,7 +143,7 @@ def __init__(self, fname = None, ff = 'amber99sb'): self.has_vsites4 = False if fname: self.read(fname, ff = ff) - + def read(self,fname, ff = None): if not hasattr(fname,"readlines"): lines = open(fname).readlines() @@ -160,7 +160,7 @@ def read(self,fname, ff = None): self.atomtypes = read_atomtypes(lines,ff) self.read_vsites2(lines) - + def write(self,fname): if not hasattr(fname,"write"): fp = open(fname,"w") @@ -178,17 +178,17 @@ def write(self,fname): write_itp_dihedrals(fp, self.dihedrals) if self.has_vsites2: self.write_itp_vsites2(fp) - + def write_itp_vsites2(self, fp ): - print >>fp, '[ virtual_sites2 ]' + print('[ virtual_sites2 ]', file=fp) for v in self.virtual_sites2: - print >>fp, "%8d %8d %8d %s %s" % (v[0].id, v[1].id, v[2].id, v[3], v[4]) - + print("%8d %8d %8d %s %s" % (v[0].id, v[1].id, v[2].id, v[3], v[4]), file=fp) + def set_name(self, name): self.name = name for atom in self.atoms: atom.resname = name - + def as_rtp(self): for i, bond in enumerate(self.bonds): id1 = bond[0] @@ -202,7 +202,7 @@ def as_rtp(self): self.angles[i][0] = self.atoms[id1-1] self.angles[i][1] = self.atoms[id2-1] self.angles[i][2] = self.atoms[id3-1] - + for i, dih in enumerate(self.dihedrals): id1 = dih[0] id2 = dih[1] @@ -230,7 +230,7 @@ def id2atoms(self): id2 = bond[1] self.bonds[i][0] = self.atoms[id1-1] self.bonds[i][1] = self.atoms[id2-1] - + for i, pairs in enumerate(self.pairs): id1 = pairs[0] id2 = pairs[1] @@ -244,7 +244,7 @@ def id2atoms(self): self.angles[i][0] = self.atoms[id1-1] self.angles[i][1] = self.atoms[id2-1] self.angles[i][2] = self.atoms[id3-1] - + for i, dih in enumerate(self.dihedrals): id1 = dih[0] id2 = dih[1] @@ -255,57 +255,57 @@ def id2atoms(self): self.dihedrals[i][2] = self.atoms[id3-1] self.dihedrals[i][3] = self.atoms[id4-1] - - + + def write_rtp(self, filename ='mol.rtp'): fp = open(filename,'w') - print >>fp, '[ %s ]' % self.name - print >>fp, ' [ atoms ]' + print('[ %s ]' % self.name, file=fp) + print(' [ atoms ]', file=fp) for atom in self.atoms: - print >>fp, "%8s %-12s %8.6f %5d" % \ - (atom.name,atom.atomtype,atom.q,atom.cgnr) + print("%8s %-12s %8.6f %5d" % \ + (atom.name,atom.atomtype,atom.q,atom.cgnr), file=fp) - print >>fp, '\n [ bonds ]' + print('\n [ bonds ]', file=fp) for bond in self.bonds: - if len(bond)<=3: - print >>fp, "%8s %8s "% \ - (bond[0].name, bond[1].name) - else: - print >>fp, "%8s %8s %8.4f %8.4f "% \ - (bond[0].name, bond[1].name, bond[3], bond[4]) - - - print >>fp, '\n [ angles ]' + if len(bond)<=3: + print("%8s %8s "% \ + (bond[0].name, bond[1].name), file=fp) + else: + print("%8s %8s %8.4f %8.4f "% \ + (bond[0].name, bond[1].name, bond[3], bond[4]), file=fp) + + + print('\n [ angles ]', file=fp) for angle in self.angles: - if len(angle)<=4: - print >>fp, "%8s %8s %8s "% \ - (angle[0].name, angle[1].name,angle[2].name) - elif angle[3]==5: # U-B - print >>fp, "%8s %8s %8s %8.4f %8.4f %8.4f %8.4f "% \ + if len(angle)<=4: + print("%8s %8s %8s "% \ + (angle[0].name, angle[1].name,angle[2].name), file=fp) + elif angle[3]==5: # U-B + print("%8s %8s %8s %8.4f %8.4f %8.4f %8.4f "% \ (angle[0].name, angle[1].name,angle[2].name, - angle[4],angle[5],angle[6],angle[7]) - else: - print >>fp, "%8s %8s %8s %8.4f %8.4f "% \ - (angle[0].name, angle[1].name,angle[2].name,angle[4],angle[5]) - + angle[4],angle[5],angle[6],angle[7]), file=fp) + else: + print("%8s %8s %8s %8.4f %8.4f "% \ + (angle[0].name, angle[1].name,angle[2].name,angle[4],angle[5]), file=fp) + - print >>fp, '\n [ dihedrals ]' + print('\n [ dihedrals ]', file=fp) for dih in self.dihedrals: - if len(dih)<=5: # no parameters - print >>fp, "%8s %8s %8s %s "% \ - (dih[0].name, dih[1].name,dih[2].name, dih[3].name) - elif dih[4]==3: - print >>fp, "%8s %8s %8s %s %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f "% \ + if len(dih)<=5: # no parameters + print("%8s %8s %8s %s "% \ + (dih[0].name, dih[1].name,dih[2].name, dih[3].name), file=fp) + elif dih[4]==3: + print("%8s %8s %8s %s %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f "% \ (dih[0].name, dih[1].name,dih[2].name, dih[3].name, - dih[5], dih[6], dih[7], dih[8], dih[9], dih[10]) - elif (dih[4]==1) or (dih[4]==4) or (dih[4]==9): - print >>fp, "%8s %8s %8s %s %8.4f %8.4f %8.4f "% \ + dih[5], dih[6], dih[7], dih[8], dih[9], dih[10]), file=fp) + elif (dih[4]==1) or (dih[4]==4) or (dih[4]==9): + print("%8s %8s %8s %s %8.4f %8.4f %8.4f "% \ (dih[0].name, dih[1].name,dih[2].name, dih[3].name, - dih[5], dih[6], dih[7]) + dih[5], dih[6], dih[7]), file=fp) elif (dih[4]==2) or (dih[4]==11): - print >>fp, "%8s %8s %8s %s %8.4f %8.4f "% \ + print("%8s %8s %8s %s %8.4f %8.4f "% \ (dih[0].name, dih[1].name,dih[2].name, dih[3].name, - dih[5], dih[6]) + dih[5], dih[6]), file=fp) # print >>fp, '\n [ impropers ]' # for dih in self.impropers: @@ -318,7 +318,7 @@ def write_rtp(self, filename ='mol.rtp'): # elif dih[4]==4: # print >>fp, "%8s %8s %8s %s %8.4f %8.4f %8.4f "% \ # (dih[0].name, dih[1].name,dih[2].name, dih[3].name, dih[5], dih[6], dih[7]) - + def read_vsites2(self, lines): starts = [] @@ -333,7 +333,7 @@ def read_vsites2(self, lines): for line in lst: entr = line.split() idx = [int(x) for x in entr[:3]] - + func = int(entr[3]) try: rest = ' '.join(entr[4:]) @@ -358,7 +358,7 @@ def read_vsites3(self, lines): for line in lst: entr = line.split() idx = [int(x) for x in entr[:4]] - + func = int(entr[4]) try: rest = ' '.join(entr[5:]) @@ -383,7 +383,7 @@ def read_vsites4(self, lines): for line in lst: entr = line.split() idx = [int(x) for x in entr[:5]] - + func = int(entr[5]) try: rest = ' '.join(entr[6:]) @@ -395,7 +395,7 @@ def read_vsites4(self, lines): self.atoms[idx[3]-1],\ self.atoms[idx[4]-1],\ func,rest]) - + class Topology: @@ -403,7 +403,7 @@ def __init__(self, filename = None, ff = 'amber99sb', itp=False, top = None): self.filename = filename self.is_itp = itp if self.is_itp and top == None: - print "Error:You have to provide the .top file if you read a .itp" + print("Error:You have to provide the .top file if you read a .itp") sys.exit(1) if top is not None: self.topfile = top @@ -433,8 +433,8 @@ def __init__(self, filename = None, ff = 'amber99sb', itp=False, top = None): self.NBParams = NBParser( l ) # self.types, self.bond_lib, self.ang_lib, self.dih_lib = \ # read_ff(self.topfile,ff=ff) - self.assign_fftypes() - + self.assign_fftypes() + def read_top(self, fname, ff = 'amber99sb'): if not hasattr(fname,"readlines"): lines = open(fname).readlines() @@ -461,7 +461,7 @@ def read_top(self, fname, ff = 'amber99sb'): if not self.is_itp: self.read_system(lines) self.read_molecules(lines) - + def assign_forcefield_parameters(self, eval_cpp = True): if eval_cpp: proc = cpp.PreProcessor() @@ -470,14 +470,14 @@ def assign_forcefield_parameters(self, eval_cpp = True): for d in self.dihedrals: if len(d) == 6: if not hasattr(d[5],"append"): - if self.cpp_dic.has_key(d[5]): + if d[5] in self.cpp_dic: d[5] = [float(x) for x in self.cpp_dic[d[5]].split()] elif len(d) == 7: if not hasattr(d[5],"append"): - if self.cpp_dic.has_key(d[5]): + if d[5] in self.cpp_dic: d[5] = [float(x) for x in self.cpp_dic[d[5]].split()] if not hasattr(d[6],"append"): - if self.cpp_dic.has_key(d[6]): + if d[6] in self.cpp_dic: d[6] = [float(x) for x in self.cpp_dic[d[6]].split()] self.make_bond_params() self.make_angle_params() @@ -505,7 +505,7 @@ def make_Bstates(self, subset = None): else: atomlist = self.atoms for atom in atomlist: - atom.atomtypeB = atom.atomtype + atom.atomtypeB = atom.atomtype atom.mB = atom.m atom.qB = atom.q @@ -556,8 +556,8 @@ def read_system(self,lines): lst = readSection(lines,'[ system ]','[') self.system = lst[0].strip() - - + + def read_atoms(self,lines): lst = readSection(lines,'[ atoms ]','[') self.atoms = [] @@ -586,14 +586,14 @@ def read_bonds(self,lines): lB = float(entries[5]) kB = float(entries[6]) self.bonds.append([self.atoms[idx[0]-1], self.atoms[idx[1]-1], idx[2], [lA,kA],[lB,kB]]) - + def read_pairs(self,lines): lst = readSection(lines,'[ pairs ]','[') self.pairs = [] for line in lst: idx = [int(x) for x in line.split()] self.pairs.append([self.atoms[idx[0]-1], self.atoms[idx[1]-1], idx[2]]) - + def read_constraints(self,lines): lst = readSection(lines,'[ constraints ]','[') self.constraints = [] @@ -602,7 +602,7 @@ def read_constraints(self,lines): self.constraints.append([self.atoms[idx[0]-1], self.atoms[idx[1]-1], idx[2]]) if self.constraints: self.have_constraints = True - + def read_angles(self, lines): lst = readSection(lines,'[ angles ]','[') angles = [] @@ -626,7 +626,7 @@ def read_angles(self, lines): kB = float(entries[7]) self.angles.append([self.atoms[idx[0]-1], self.atoms[idx[1]-1], \ self.atoms[idx[2]-1], idx[3], [lA,kA],[lB,kB]]) - + def read_dihedrals(self, lines): starts = [] dih = [] @@ -638,7 +638,7 @@ def read_dihedrals(self, lines): for line in lst: entr = line.split() idx = [int(x) for x in entr[:4]] - + func = int(entr[4]) try: rest = ' '.join(entr[5:]) @@ -662,7 +662,7 @@ def read_vsites3(self, lines): for line in lst: entr = line.split() idx = [int(x) for x in entr[:4]] - + func = int(entr[4]) try: rest = ' '.join(entr[5:]) @@ -687,7 +687,7 @@ def read_vsites4(self, lines): for line in lst: entr = line.split() idx = [int(x) for x in entr[:5]] - + func = int(entr[5]) try: rest = ' '.join(entr[6:]) @@ -723,7 +723,7 @@ def read_moleculetype(self, lines): l = readSection(lines,'[ moleculetype ]','[') if l: self.name, self.nexcl = l[0].split()[0], int(l[0].split()[1]) - + def set_molecule(self, molname, n): mol_exists = False for i, mol in enumerate(self.molecules): @@ -732,7 +732,7 @@ def set_molecule(self, molname, n): mol_exists = True if not mol_exists: self.molecules.append([molname,n]) - + def del_molecule(self, molname): if not hasattr(molname,"append"): molname = [molname] @@ -741,7 +741,7 @@ def del_molecule(self, molname): if m[0] not in molname: new.append(m) self.molecules = new - + def write_top(self, outfile, stateBonded = 'AB', stateTypes = 'AB', stateQ = 'AB', scale_mass = False, dummy_qA = 'on', dummy_qB = 'on', target_qB = [], full_morphe = True): @@ -769,19 +769,19 @@ def write_top(self, outfile, stateBonded = 'AB', stateTypes = 'AB', stateQ = 'AB self.write_system(fp) self.write_molecules(fp) fp.close() - + def write_header(self,fp): for line in self.header: - print >>fp, line + print(line, file=fp) def write_footer(self,fp): for line in self.footer: - print >>fp, line + print(line, file=fp) def write_moleculetype(self, fp): - print >>fp, '[ moleculetype ]' - print >>fp, '; Name nrexcl' - print >>fp, '%s %d' % (self.name,self.nrexcl) + print('[ moleculetype ]', file=fp) + print('; Name nrexcl', file=fp) + print('%s %d' % (self.name,self.nrexcl), file=fp) def __atoms_morphe( self, atoms ): for atom in atoms: @@ -792,11 +792,11 @@ def __atomtypes_morphe(self, atoms): for atom in atoms: if atom.atomtypeB is not None and atom.atomtype != atom.atomtypeB: return True return False - + def __is_perturbed_residue( self, residue ): if self.__atoms_morphe(residue.atoms): return True return False - + def __last_perturbed_atom(self, r): max_order = 0 @@ -806,7 +806,7 @@ def __last_perturbed_atom(self, r): if not atom.atomtype.startswith('DUM') and not atom.atomtypeB.startswith('DUM'): last_atom = atom if last_atom == None: - print >>sys.stderr, 'Error: Could not find a perturbed atom to put rest charges on !' + print('Error: Could not find a perturbed atom to put rest charges on !', file=sys.stderr) sys.exit(1) return last_atom @@ -814,7 +814,7 @@ def check_special_dihedrals( self ): for d in self.dihedrals: A, B = self.check_case( d[:4] ) if ('D' not in A and 'D' in B) or ('D' in A and 'D' not in B): - print d[0].name, d[1].name, d[2].name, d[3].name, d[4:], A, B + print(d[0].name, d[1].name, d[2].name, d[3].name, d[4:], A, B) def write_atoms(self, fp, charges = 'AB', atomtypes = 'AB', dummy_qA = 'on',\ dummy_qB = 'on', scale_mass=True, target_qB = [], full_morphe = True): @@ -824,7 +824,7 @@ def write_atoms(self, fp, charges = 'AB', atomtypes = 'AB', dummy_qA = 'on',\ for r in self.residues: if self.__is_perturbed_residue(r): target_chargeB = target_qB.pop(0) - print 'Making target charge %g for residue %s' % (round(target_chargeB,5), r.resname) + print('Making target charge %g for residue %s' % (round(target_chargeB,5), r.resname)) for atom in r.atoms: if self.__atoms_morphe([atom]): if charges == 'AB': # we move the charges from state A to state B @@ -865,24 +865,24 @@ def write_atoms(self, fp, charges = 'AB', atomtypes = 'AB', dummy_qA = 'on',\ else: atom.qqA = atom.q atom.qqB = atom.q - qA_tot = sum(map(lambda a: a.qqA, r.atoms)) - qB_tot = sum(map(lambda a: a.qqB, r.atoms)) + qA_tot = sum([a.qqA for a in r.atoms]) + qB_tot = sum([a.qqB for a in r.atoms]) if qB_tot != target_chargeB: - print 'State B has total charge of %g' % round(qB_tot,5) - print 'Applying charge correction to ensure integer charges' + print('State B has total charge of %g' % round(qB_tot,5)) + print('Applying charge correction to ensure integer charges') latom = self.__last_perturbed_atom(r) - print 'Selecting atom %d-%s (%s) as perturbed atom with highest order' % (latom.id,latom.name, latom.resname) + print('Selecting atom %d-%s (%s) as perturbed atom with highest order' % (latom.id,latom.name, latom.resname)) newqB = latom.qqB-(qB_tot-target_chargeB) - print 'Changing chargeB of atom %s from %g to %g' % (latom.name, latom.qqB,newqB) + print('Changing chargeB of atom %s from %g to %g' % (latom.name, latom.qqB,newqB)) latom.qqB = newqB - qB_tot = sum(map(lambda a: a.qqB, r.atoms)) - print 'New total charge of B-state is %g' % round(qB_tot,5) + qB_tot = sum([a.qqB for a in r.atoms]) + print('New total charge of B-state is %g' % round(qB_tot,5)) else: - print 'No corrections applied to ensure integer charges' + print('No corrections applied to ensure integer charges') - print >>fp,'\n [ atoms ]' - print >>fp, '; nr type resnr residue atom cgnr charge mass typeB chargeB massB' + print('\n [ atoms ]', file=fp) + print('; nr type resnr residue atom cgnr charge mass typeB chargeB massB', file=fp) al = self.atoms for atom in al: if self.__atoms_morphe([atom]): @@ -916,15 +916,15 @@ def write_atoms(self, fp, charges = 'AB', atomtypes = 'AB', dummy_qA = 'on',\ else: qqA = atom.q qqB = atom.qB - print >>fp , '%6d%11s%7d%7s%7s%7d%11.6f%11.4f%11s%11.6f%11.4f' % \ + print('%6d%11s%7d%7s%7s%7d%11.6f%11.4f%11s%11.6f%11.4f' % \ (atom.id, atA, atom.resnr, atom.resname, atom.name, \ - atom.cgnr, qqA, mA, atB, qqB, mB) + atom.cgnr, qqA, mA, atB, qqB, mB), file=fp) self.qA+=qqA self.qB+=qqB else: - print >>fp , '%6d%11s%7d%7s%7s%7d%11.6f%11.4f' % \ + print('%6d%11s%7d%7s%7s%7d%11.6f%11.4f' % \ (atom.id, atom.atomtype, atom.resnr, atom.resname, atom.name, \ - atom.cgnr, atom.q, atom.m) + atom.cgnr, atom.q, atom.m), file=fp) self.qA+=atom.q self.qB+=atom.q # write qB of latom to qA @@ -950,80 +950,80 @@ def write_atoms(self, fp, charges = 'AB', atomtypes = 'AB', dummy_qA = 'on',\ def write_bonds(self,fp, state = 'AB'): - print >>fp,'\n [ bonds ]' - print >>fp, '; ai aj funct c0 c1 c2 c3' + print('\n [ bonds ]', file=fp) + print('; ai aj funct c0 c1 c2 c3', file=fp) for b in self.bonds: if len(b) == 3: - print >>fp, '%6d %6d %6d' % (b[0].id, b[1].id, b[2]) + print('%6d %6d %6d' % (b[0].id, b[1].id, b[2]), file=fp) elif len(b) == 4: s = ' '+' '.join([str(x) for x in b[3]]) - print >>fp, '%6d %6d %6d %s' % (b[0].id, b[1].id, b[2], s) + print('%6d %6d %6d %s' % (b[0].id, b[1].id, b[2], s), file=fp) else: lA = b[3][1] kA = b[3][2] lB = b[4][1] kB = b[4][2] if state == 'AB': - print >>fp, '%6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % \ - (b[0].id, b[1].id, b[2],lA,kA, lB, kB) + print('%6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % \ + (b[0].id, b[1].id, b[2],lA,kA, lB, kB), file=fp) elif state == 'AA': - print >>fp, '%6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % \ - (b[0].id, b[1].id, b[2],lA, kA, lA, kA) + print('%6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % \ + (b[0].id, b[1].id, b[2],lA, kA, lA, kA), file=fp) elif state == 'BB': - print >>fp, '%6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % \ - (b[0].id, b[1].id, b[2],lB, kB, lB, kB) + print('%6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % \ + (b[0].id, b[1].id, b[2],lB, kB, lB, kB), file=fp) def write_pairs(self, fp): # CHECK HOW THIS GOES WITH B-STATES - print >>fp,'\n [ pairs ]' - print >>fp, '; ai aj funct c0 c1 c2 c3' + print('\n [ pairs ]', file=fp) + print('; ai aj funct c0 c1 c2 c3', file=fp) for p in self.pairs: - print >>fp, '%6d %6d %6d' % (p[0].id, p[1].id, p[2]) + print('%6d %6d %6d' % (p[0].id, p[1].id, p[2]), file=fp) def write_constraints(self, fp): # CHECK HOW THIS GOES WITH B-STATES - print >>fp,'\n [ constraints ]' - print >>fp, '; ai aj funct c0 c1 c2 c3' + print('\n [ constraints ]', file=fp) + print('; ai aj funct c0 c1 c2 c3', file=fp) for p in self.constraints: - print >>fp, '%6d %6d %6d' % (p[0].id, p[1].id, p[2]) + print('%6d %6d %6d' % (p[0].id, p[1].id, p[2]), file=fp) def write_angles(self,fp, state='AB'): - print >>fp,'\n [ angles ]' - print >>fp, '; ai aj ak funct c0 c1 c2 c3' + print('\n [ angles ]', file=fp) + print('; ai aj ak funct c0 c1 c2 c3', file=fp) for ang in self.angles: if len(ang) == 4: - print >>fp, '%6d %6d %6d %6d' % (ang[0].id, ang[1].id, ang[2].id,ang[3]) + print('%6d %6d %6d %6d' % (ang[0].id, ang[1].id, ang[2].id,ang[3]), file=fp) else: if state == 'AB': - print >>fp, '%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ + print('%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ (ang[0].id, ang[1].id, ang[2].id,ang[3], ang[4][1], \ - ang[4][2], ang[5][1], ang[5][2], ang[0].name, ang[1].name, ang[2].name) + ang[4][2], ang[5][1], ang[5][2], ang[0].name, ang[1].name, ang[2].name), file=fp) elif state == 'AA': - print >>fp, '%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ + print('%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ (ang[0].id, ang[1].id, ang[2].id,ang[3], ang[4][1], \ - ang[4][2], ang[4][1], ang[4][2], ang[0].name, ang[1].name, ang[2].name) + ang[4][2], ang[4][1], ang[4][2], ang[0].name, ang[1].name, ang[2].name), file=fp) elif state == 'BB': - print >>fp, '%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ + print('%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ (ang[0].id, ang[1].id, ang[2].id,ang[3], ang[5][1], \ - ang[5][2], ang[5][1], ang[5][2], ang[0].name, ang[1].name, ang[2].name) + ang[5][2], ang[5][1], ang[5][2], ang[0].name, ang[1].name, ang[2].name), file=fp) def write_dihedrals(self, fp, state='AB'): - print >>fp,'\n [ dihedrals ]' - print >>fp,'; ai aj ak al funct c0 c1 c2 c3 c4 c5' + print('\n [ dihedrals ]', file=fp) + print('; ai aj ak al funct c0 c1 c2 c3 c4 c5', file=fp) for d in self.dihedrals: if len(d) == 5: - print >>fp, "%6d %6d %6d %6d %4d" % ( d[0].id, d[1].id, d[2].id, d[3].id, d[4]) + print("%6d %6d %6d %6d %4d" % ( d[0].id, d[1].id, d[2].id, d[3].id, d[4]), file=fp) elif len(d) == 6: - print >>fp, "%6d %6d %6d %6d %4d %s" % ( d[0].id, d[1].id, d[2].id, d[3].id, d[4], d[5]) + print("%6d %6d %6d %6d %4d %s" % ( d[0].id, d[1].id, d[2].id, d[3].id, d[4], d[5]), file=fp) elif len(d) == 7: A, B = self.check_case(d[:4]) ast = d[5] bs = d[6] if ast == None or bs == None: - print d[0].name, d[1].name, d[2].name, d[3].name, d[0].atomtype, d[1].atomtype, d[2].atomtype, d[3].atomtype, d[0].atomtypeB, d[1].atomtypeB, d[2].atomtypeB, d[3].atomtypeB - print d[0].type, d[1].type, d[2].type, d[3].type, d[0].typeB, d[1].typeB, d[2].typeB, d[3].typeB + print(d[0].name, d[1].name, d[2].name, d[3].name, d[0].atomtype, d[1].atomtype, d[2].atomtype, d[3].atomtype, d[0].atomtypeB, d[1].atomtypeB, d[2].atomtypeB, d[3].atomtypeB) + print(d[0].type, d[1].type, d[2].type, d[3].type, d[0].typeB, d[1].typeB, d[2].typeB, d[3].typeB) if ast == 'NULL': if d[4] == 3: # Ryckaert-Bellemans ast = ' '.join(["%g" % x for x in [0,0,0,0,0,0]]) @@ -1033,72 +1033,72 @@ def write_dihedrals(self, fp, state='AB'): ast = ' '.join(["%g" % x for x in d[5][1:]]) if bs == 'NULL': if d[4] == 3: - bs = ' '.join(["%g" % x for x in [0,0,0,0,0,0]]) + bs = ' '.join(["%g" % x for x in [0,0,0,0,0,0]]) elif d[4] == 1: bs = ' '.join(["%g" % x for x in [0,0,0]]) elif bs !='NULL' and hasattr(bs,"append"): bs = ' '.join(["%g" % x for x in d[6][1:]]) if state == 'AB': - print >>fp, "%6d %6d %6d %6d %4d %s %s ; %s %s %s %s %s %s %s %s (%s->%s)" % \ + print("%6d %6d %6d %6d %4d %s %s ; %s %s %s %s %s %s %s %s (%s->%s)" % \ ( d[0].id, d[1].id, d[2].id, d[3].id, d[4], ast, bs, d[0].name,d[1].name,d[2].name,d[3].name, \ - d[0].type,d[1].type,d[2].type,d[3].type,A,B) + d[0].type,d[1].type,d[2].type,d[3].type,A,B), file=fp) elif state == 'AA': - print >>fp, "%6d %6d %6d %6d %4d %s %s ; %s %s %s %s %s %s %s %s (%s->%s)" % \ + print("%6d %6d %6d %6d %4d %s %s ; %s %s %s %s %s %s %s %s (%s->%s)" % \ ( d[0].id, d[1].id, d[2].id, d[3].id, d[4], ast, ast, d[0].name,d[1].name,d[2].name,d[3].name, \ - d[0].type,d[1].type,d[2].type,d[3].type, A,B) + d[0].type,d[1].type,d[2].type,d[3].type, A,B), file=fp) elif state == 'BB': - print >>fp, "%6d %6d %6d %6d %4d %s %s ; %s %s %s %s %s %s %s %s (%s->%s)" % \ + print("%6d %6d %6d %6d %4d %s %s ; %s %s %s %s %s %s %s %s (%s->%s)" % \ ( d[0].id, d[1].id, d[2].id, d[3].id, d[4], bs, bs, d[0].name,d[1].name,d[2].name,d[3].name, \ - d[0].type,d[1].type,d[2].type,d[3].type, A,B) + d[0].type,d[1].type,d[2].type,d[3].type, A,B), file=fp) def check_case(self, atoms): - A = '' - B = '' - for a in atoms: - if a.atomtype.startswith('DUM'): A += 'D' - else: A += 'A' - if a.atomtypeB is not None: - if a.atomtypeB.startswith('DUM'): B += 'D' - else: B += 'A' + A = '' + B = '' + for a in atoms: + if a.atomtype.startswith('DUM'): A += 'D' + else: A += 'A' + if a.atomtypeB is not None: + if a.atomtypeB.startswith('DUM'): B += 'D' else: B += 'A' - return A, B + else: B += 'A' + return A, B def write_vsites3(self, fp): - print >>fp,'\n [ virtual_sites3 ]' - print >>fp,'; ai aj ak al funct c0 c1' + print('\n [ virtual_sites3 ]', file=fp) + print('; ai aj ak al funct c0 c1', file=fp) for vs in self.virtual_sites3: if len(vs) == 6: - print >>fp, "%6d %6d %6d %6d %4d" % ( vs[0].id, vs[1].id, vs[2].id, vs[3].id, vs[4]) + print("%6d %6d %6d %6d %4d" % ( vs[0].id, vs[1].id, vs[2].id, vs[3].id, vs[4]), file=fp) else: sys.stderr.write('EEK! Something went wrong while writing virtual_sites3!!!!\n') - print vs + print(vs) sys.exit(1) def write_vsites4(self, fp): - print >>fp,'\n [ virtual_sites4 ]' - print >>fp,'; ai aj ak al am funct c0 c1 c2' + print('\n [ virtual_sites4 ]', file=fp) + print('; ai aj ak al am funct c0 c1 c2', file=fp) for vs in self.virtual_sites4: if len(vs) == 7: - print >>fp, "%6d %6d %6d %6d %6d %4d" % ( vs[0].id, vs[1].id, vs[2].id, vs[3].id, vs[4].id, vs[5]) + print("%6d %6d %6d %6d %6d %4d" % ( vs[0].id, vs[1].id, vs[2].id, vs[3].id, vs[4].id, vs[5]), file=fp) else: sys.stderr.write('EEK! Something went wrong while writing virtual_sites4!!!!\n') - print vs + print(vs) sys.exit(1) def write_system(self,fp): - print >>fp, '[ system ]' - print >>fp, self.system + print('[ system ]', file=fp) + print(self.system, file=fp) def write_molecules(self,fp): - print >>fp, '[ molecules ]' + print('[ molecules ]', file=fp) for mol, num in self.molecules: - print >>fp, "%s %d" % (mol,num) - + print("%s %d" % (mol,num), file=fp) + def assign_fftypes(self): for atom in self.atoms: atom.type = self.NBParams.atomtypes[atom.atomtype]['bond_type'] @@ -1106,13 +1106,13 @@ def assign_fftypes(self): atom.typeB = self.NBParams.atomtypes[atom.atomtypeB]['bond_type'] else: atom.typeB = atom.type - + def make_bond_params(self): for i, (at1,at2,func) in enumerate(self.bonds): param = get_bond_param(at1.type,at2.type,self.bond_lib) if param is None: - print 'Error! No bonded parameters found! (%s-%s)' % \ - (at1.type, at2.type) + print('Error! No bonded parameters found! (%s-%s)' % \ + (at1.type, at2.type)) sys.exit(1) self.bonds[i].append(param[1:]) @@ -1120,11 +1120,11 @@ def make_angle_params(self): for i, (at1, at2, at3, func) in enumerate(self.angles): param = get_angle_param(at1.type, at2.type, at3.type, self.ang_lib) if param is None: - print 'Error! No angle parameters found! (%s-%s-%s)' % \ - (at1.type, at2.type, at3.type) + print('Error! No angle parameters found! (%s-%s-%s)' % \ + (at1.type, at2.type, at3.type)) sys.exit(1) self.angles[i].append(param[1:]) - + def make_dihedral_params(self): for i, d in enumerate(self.dihedrals): if d[5]!='': # we have a prefefined dihedral @@ -1135,14 +1135,14 @@ def make_dihedral_params(self): at3.type, at4.type, \ self.dih_lib, func) if param is None: - print 'Error! No dihedral parameters found! (%s-%s-%s-%s)' % \ - (at1.type, at2.type, at3.type, at4.type) - print func, dih + print('Error! No dihedral parameters found! (%s-%s-%s-%s)' % \ + (at1.type, at2.type, at3.type, at4.type)) + print(func, dih) sys.exit(1) del self.dihedrals[i][-1] self.dihedrals[i].append(param[1:]) - - + + def cpp_parse_file(fn,cpp_defs=[],cpp_path=[os.environ.get('GMXLIB')] ): @@ -1259,13 +1259,13 @@ def __get_rtp_entry( key, lines ): else: r.append(line) return r - + def __read_rtp_atoms(resname, lines ): atoms = [] for line in lines: entr = line.split() - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[0]): + if resname in _aliases : + if entr[0] in _aliases[resname]: entr[0] = _aliases[resname][entr[0]] entr[2] = float(entr[2]) entr[3] = int(entr[3]) @@ -1277,12 +1277,12 @@ def __read_rtp_bonds( resname, lines ): for line in lines: entr = line.split() if entr[0] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[0]): + if resname in _aliases : + if entr[0] in _aliases[resname]: entr[0] = _aliases[resname][entr[0]] if entr[1] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[1]): + if resname in _aliases : + if entr[1] in _aliases[resname]: entr[1] = _aliases[resname][entr[1]] bonds.append(entr) return bonds @@ -1292,20 +1292,20 @@ def __read_rtp_dihedrals( resname, lines ): for line in lines: entr = line.split() if entr[0] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[0]): + if resname in _aliases : + if entr[0] in _aliases[resname]: entr[0] = _aliases[resname][entr[0]] if entr[1] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[1]): + if resname in _aliases : + if entr[1] in _aliases[resname]: entr[1] = _aliases[resname][entr[1]] if entr[2] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[2]): + if resname in _aliases : + if entr[2] in _aliases[resname]: entr[2] = _aliases[resname][entr[2]] if entr[3] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[3]): + if resname in _aliases : + if entr[3] in _aliases[resname]: entr[3] = _aliases[resname][entr[3]] if len(entr) == 5: diheds.append(entr) @@ -1318,20 +1318,20 @@ def __read_rtp_impropers( resname, lines ): for line in lines: entr = line.split() if entr[0] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[0]): + if resname in _aliases : + if entr[0] in _aliases[resname]: entr[0] = _aliases[resname][entr[0]] if entr[1] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[1]): + if resname in _aliases : + if entr[1] in _aliases[resname]: entr[1] = _aliases[resname][entr[1]] if entr[2] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[2]): + if resname in _aliases : + if entr[2] in _aliases[resname]: entr[2] = _aliases[resname][entr[2]] if entr[3] not in ['+','-']: - if _aliases.has_key( resname ) : - if _aliases[resname].has_key(entr[3]): + if resname in _aliases : + if entr[3] in _aliases[resname]: entr[3] = _aliases[resname][entr[3]] if len(entr) == 5: improps.append(entr) @@ -1368,7 +1368,7 @@ def read_rtp( filename ): } sys.stderr.write('\ndone...\n' ) return rtp_entries - + def get_rtp_entry(key, filename = 'ffamber99sb.rtp'): @@ -1379,8 +1379,8 @@ def get_rtp_entry(key, filename = 'ffamber99sb.rtp'): idx = 0 for line in lines: if line.strip()[1:-1].strip() == key: - idx = lines.index(line) - break + idx = lines.index(line) + break for line in lines[idx+1:]: if line.strip().startswith('['): if line.strip()[1:-1].strip() not in \ @@ -1458,20 +1458,20 @@ def read_itp_atoms(lines): return al def write_itp_atoms(fp,al): - print >>fp, '[ atoms ]' - print >>fp,'; nr type resnr residue atom cgnr charge mass typeB chargeB' + print('[ atoms ]', file=fp) + print('; nr type resnr residue atom cgnr charge mass typeB chargeB', file=fp) for atom in al: if atom.atomtypeB is not None: - print >>fp , '%6d %11s %7d%7s%7s%7d%11.6f%11.4f %11s%11.6f%11.4f' % \ - (atom.id, atom.atomtype, atom.resnr, atom.resname, atom.name, \ - atom.cgnr, atom.q, atom.m, atom.atomtypeB, atom.qB, atom.mB) + print('%6d %11s %7d%7s%7s%7d%11.6f%11.4f %11s%11.6f%11.4f' % \ + (atom.id, atom.atomtype, atom.resnr, atom.resname, atom.name, \ + atom.cgnr, atom.q, atom.m, atom.atomtypeB, atom.qB, atom.mB), file=fp) else: - print >>fp , '%6d %11s %7d%7s%7s%7d%11.6f%11.4f' % \ + print('%6d %11s %7d%7s%7s%7d%11.6f%11.4f' % \ (atom.id, atom.atomtype, atom.resnr, atom.resname, atom.name, \ - atom.cgnr, atom.q, atom.m) + atom.cgnr, atom.q, atom.m), file=fp) def write_itp_bonds(fp,bonds): - print >>fp, '[ bonds ]' + print('[ bonds ]', file=fp) for b in bonds: if isinstance(b[0],Atom): tmp = [b[0].id, b[1].id]+b[2:] @@ -1485,10 +1485,10 @@ def write_itp_bonds(fp,bonds): out += form % item elif len(item) > 0: out += "%6s " % item - print >>fp, out + print(out, file=fp) def write_itp_pairs(fp,pairs): - print >>fp, '[ pairs ]' + print('[ pairs ]', file=fp) for p in pairs: if isinstance(p[0],Atom): tmp = [p[0].id, p[1].id]+p[2:] @@ -1502,10 +1502,10 @@ def write_itp_pairs(fp,pairs): out += form % item elif len(item) > 0: out += "%6s " % item - print >>fp, out + print(out, file=fp) def write_itp_angles(fp,angles): - print >>fp, '[ angles ]' + print('[ angles ]', file=fp) for a in angles: if isinstance(a[0],Atom): tmp = [a[0].id, a[1].id, a[2].id]+a[3:] @@ -1519,11 +1519,11 @@ def write_itp_angles(fp,angles): out += form % item elif len(item) > 0: out += "%6s " % item - print >>fp, out + print(out, file=fp) def write_itp_dihedrals(fp,dihedrals): - print >>fp, '[ dihedrals ]' + print('[ dihedrals ]', file=fp) for d in dihedrals: if isinstance(d[0],Atom): tmp = [d[0].id, d[1].id, d[2].id, d[3].id]+d[4:] @@ -1537,14 +1537,14 @@ def write_itp_dihedrals(fp,dihedrals): out += form % item elif len(item) > 0: out += "%6s " % item - print >>fp, out + print(out, file=fp) def write_itp_moleculetype(fp,name,nrexcl): - print >>fp, '[ moleculetype ]' - print >>fp, '; Name nrexcl' - print >>fp, '%s %d' % (name,nrexcl) - + print('[ moleculetype ]', file=fp) + print('; Name nrexcl', file=fp) + print('%s %d' % (name,nrexcl), file=fp) + def read_itp_bonds(lines): lst = readSection(lines,'[ bonds ]','[') bonds = [] @@ -1630,14 +1630,14 @@ def read_gaff_top(fname): # atypes = read_atomtypes(lines, ff = 'amber03') # itp.atomtypes = atypes return itp - + class MDPError(Exception): def __init__(self, s): self.s = s def __str__(self): return repr(self.s) - + class MDP: def __init__(self, fn = None): @@ -1678,7 +1678,7 @@ def __init__(self, fn = None): ['pbc' , 'xyz'], ['periodic_molecules' , 'no'], ['rlist' , 1.2], - ['cutoff-scheme' , 'verlet'], + ['cutoff-scheme' , 'verlet'], ['coulombtype' , 'PME'], ['rcoulomb-switch' , 0], ['rcoulomb' , 1.1], @@ -1770,7 +1770,7 @@ def __init__(self, fn = None): ['sc-alpha' , 0.3], ['sc-power' , 1], ['sc-sigma' , 0.25], - ['sc-coul' , 'yes'], + ['sc-coul' , 'yes'], ['couple-moltype' ,''], ['couple-lambda0' , 'vdw-q'], ['couple-lambda1' , 'vdw-q'], @@ -1798,13 +1798,13 @@ def __init__(self, fn = None): ['userreal3' , 0], ['userreal4' , 0] ]) - + if fn: self.read(fn) def __str__(self): line = '' - for key, val in self.parameters.items(): + for key, val in list(self.parameters.items()): if hasattr(val,"append"): s = '' for x in val: @@ -1813,17 +1813,17 @@ def __str__(self): s = str(val) line+="%-25s = %s\n" % (key, s) return line - + def __setitem__(self,item,value): - if not self.parameters.has_key(item): - raise MDPError, "No such option %s" % item - + if item not in self.parameters: + raise MDPError("No such option %s" % item) + self.parameters[item] = value def __getitem__(self, item): return self.parameters[item] - + def write(self, fp = None): if fp is None: @@ -1831,7 +1831,7 @@ def write(self, fp = None): else: if not hasattr(fp,"write"): fp = open(fp,"w") - print >>fp, self + print(self, file=fp) def read(self, filename): lines = open(filename).readlines() @@ -1840,7 +1840,7 @@ def read(self, filename): entr = line.split('=') key = entr[0].strip() val = entr[1].strip().split() - if not self.parameters.has_key(key): + if key not in self.parameters: self.parameters[key] = val # print 'Warning! Ignoring entry \'%s\'' % key else: @@ -1878,7 +1878,7 @@ def make_amber_residue_names(model): res.set_resname(rr) else: res.set_resname('CYM') - + else: res.set_resname('CYN') lysl = model.fetch_residues('LYS') @@ -1937,7 +1937,7 @@ def make_amber_residue_names(model): o1.name = 'OC1' o2.name = 'OC2' except: - print >>sys.stderr, 'pymacs_Warning_> No terminal oxygen atoms found in chain %s' % chain.id + print('pymacs_Warning_> No terminal oxygen atoms found in chain %s' % chain.id, file=sys.stderr) @@ -1946,7 +1946,7 @@ def assign_ffamber99sb_params(m): m.rename_atoms() for c in m.chains: c.make_residue_tree() - + make_amber_residue_names( m) rtp = RTPParser('ffamber99sb.rtp') rtp.assign_params(m) @@ -1955,7 +1955,7 @@ def assign_ffamber99sb_params(m): nb.assign_params( m ) bo.assign_params( m ) rtp.assign_dihedral_params( m, bo.directives ) - + def bond_energy(m): @@ -1980,20 +1980,19 @@ def nb_energy( m ): def energy(m): - bond_ene = bond_energy( m ) + bond_ene = bond_energy( m ) angle_ene = angle_energy( m ) dihedral_ene = dihedral_energy( m ) improper_ene = improper_energy ( m ) lj14_ene = lj14_energy( m ) coul14_ene = coul14_energy( m ) nb_ene = nb_energy( m ) -## print 'bonds = ', bond_ene +## print 'bonds = ', bond_ene ## print 'angles = ',angle_ene ## print 'dihedrals = ',dihedral_ene ## print 'impropers = ',improper_ene ## print 'nb = ',nb_ene ## print 'lj14 = ',lj14_ene ## print 'coul14 = ',coul14_ene - - return bond_ene + angle_ene + dihedral_ene + improper_ene + nb_ene + lj14_ene + coul14_ene + return bond_ene + angle_ene + dihedral_ene + improper_ene + nb_ene + lj14_ene + coul14_ene diff --git a/pmx/forcefield2.py b/pmx/forcefield2.py index 3d26656b..e284475a 100644 --- a/pmx/forcefield2.py +++ b/pmx/forcefield2.py @@ -34,17 +34,17 @@ Functions to read gromacs forcefield files """ import sys,os,re, copy -from parser import * -import cpp -from atom import Atom -from molecule import Molecule -from odict import * -from library import _aliases -from ffparser import * -import _pmx as _p +from .parser import * +from . import cpp +from .atom import Atom +from .molecule import Molecule +from .odict import * +from .library import _aliases +from .ffparser import * +from . import _pmx as _p def TR ( s ): - print "pmx.forcefield_> " + s + print("pmx.forcefield_> " + s) #def cpp_parse_file(fn,cpp_defs=[],cpp_path=[os.environ.get('GMXDATA')+'/top'] ): def cpp_parse_file(fn,cpp_defs=[],cpp_path=[os.environ.get('GMXLIB')], itp=False, ffpath=None ): @@ -57,17 +57,17 @@ def cpp_parse_file(fn,cpp_defs=[],cpp_path=[os.environ.get('GMXLIB')], itp=False incs.append('-I%s' % i) if itp: cmd1 = 'cpp -traditional %s %s %s ' % (' '.join(defs),' '.join(incs),fn) - l1 = os.popen(cmd1,'r').readlines() - if ffpath != None: - ffname = ffpath+'/forcefield.itp' + l1 = os.popen(cmd1,'r').readlines() + if ffpath != None: + ffname = ffpath+'/forcefield.itp' cmd2 = 'cpp -traditional %s %s %s ' % (' '.join(defs),' '.join(incs),ffname) - l2 = os.popen(cmd2,'r').readlines() - return(l1+l2) - else: - return(l1) + l2 = os.popen(cmd2,'r').readlines() + return(l1+l2) + else: + return(l1) else: cmd = 'cpp -traditional %s %s %s ' % (' '.join(defs),' '.join(incs),fn) - return os.popen(cmd,'r').readlines() + return os.popen(cmd,'r').readlines() @@ -93,7 +93,7 @@ def __init__(self, filename, version = 'old'): self.constraints = [] self.have_constraints = False self.pairs = [] - self.cmap = [] + self.cmap = [] self.angles = [] self.dihedrals = [] self.virtual_sites2 = [] @@ -102,12 +102,12 @@ def __init__(self, filename, version = 'old'): self.has_vsites2 = False self.has_vsites3 = False self.has_vsites4 = False - self.has_posre = False + self.has_posre = False self.has_exclusions = False self.exclusions = [] self.has_ii = False # intermolecular_interactions self.ii = {} # ii is a dictionary, which containts bonds, angles, dihedrals - self.posre = [] + self.posre = [] self.molecules = [] self.system = '' self.qA = 0. @@ -116,7 +116,7 @@ def __init__(self, filename, version = 'old'): self.read() #=============================================================================== # read functions - + def read( self ): lines = open(self.filename).readlines() lines = kickOutComments(lines,';') @@ -140,12 +140,12 @@ def read( self ): self.read_vsites4(lines) self.read_exclusions(lines) if self.has_posre: - self.read_posre(posre_sections) + self.read_posre(posre_sections) self.__make_residues() if not self.is_itp: self.read_system(lines) self.read_molecules(lines) - + def __atom_from_top_line(self, line): entr = line.split() idx = int(entr[0]) @@ -204,7 +204,7 @@ def __make_residues(self): self.residues.append( mol ) for r in self.residues: atom.molecule = r - + def read_system(self,lines): @@ -235,11 +235,11 @@ def read_atomtypes( self, lines): try: lst = parseList('ssiffsff',l) # opls except: - print 'Could not read atomtype format' + print('Could not read atomtype format') if len(lst)>0: self.has_atomtypes = True self.atomtypes = lst - + def read_header(self, lines): ret = [] for line in lines: @@ -290,14 +290,14 @@ def read_bonds(self,lines): lB = float(entries[5]) kB = float(entries[6]) self.bonds.append([self.atoms[idx[0]-1], self.atoms[idx[1]-1], idx[2], [idx[2],lA,kA],[idx[2],lB,kB]]) - + def read_pairs(self,lines): lst = readSection(lines,'[ pairs ]','[') self.pairs = [] for line in lst: idx = [int(x) for x in line.split()] self.pairs.append([self.atoms[idx[0]-1], self.atoms[idx[1]-1], idx[2]]) - + def read_constraints(self,lines): lst = readSection(lines,'[ constraints ]','[') self.constraints = [] @@ -306,7 +306,7 @@ def read_constraints(self,lines): self.constraints.append([self.atoms[idx[0]-1], self.atoms[idx[1]-1], idx[2]]) if self.constraints: self.have_constraints = True - + def read_angles(self, lines): lst = readSection(lines,'[ angles ]','[') angles = [] @@ -337,7 +337,7 @@ def read_angles(self, lines): lA2 = float(entries[6]) kA2 = float(entries[7]) self.angles.append([self.atoms[idx[0]-1], \ - self.atoms[idx[1]-1],self.atoms[idx[2]-1],idx[3],[idx[3],lA1,kA1,lA2,kA2]]) + self.atoms[idx[1]-1],self.atoms[idx[2]-1],idx[3],[idx[3],lA1,kA1,lA2,kA2]]) elif len(entries) == 12: idx = [int(x) for x in entries[:4]] lA1 = float(entries[4]) @@ -350,8 +350,8 @@ def read_angles(self, lines): kB2 = float(entries[11]) self.angles.append([self.atoms[idx[0]-1], self.atoms[idx[1]-1], \ self.atoms[idx[2]-1], idx[3],\ - [idx[3],lA1,kA1,lA2,kA2],[idx[3],lB1,kB1,lB2,kB2]]) - + [idx[3],lA1,kA1,lA2,kA2],[idx[3],lB1,kB1,lB2,kB2]]) + def read_dihedrals(self, lines): starts = [] dih = [] @@ -363,7 +363,7 @@ def read_dihedrals(self, lines): for line in lst: entr = line.split() idx = [int(x) for x in entr[:4]] - + func = int(entr[4]) try: rest = ' '.join(entr[5:]) @@ -374,8 +374,8 @@ def read_dihedrals(self, lines): self.atoms[idx[2]-1],\ self.atoms[idx[3]-1],\ func,rest]) -# foo = (self.atoms[idx[0]-1],self.atoms[idx[1]-1],self.atoms[idx[2]-1],self.atoms[idx[3]-1],func,rest) -# print 'length %d' % len(foo) +# foo = (self.atoms[idx[0]-1],self.atoms[idx[1]-1],self.atoms[idx[2]-1],self.atoms[idx[3]-1],func,rest) +# print 'length %d' % len(foo) def read_cmap(self, lines): starts = [] cmap = [] @@ -387,7 +387,7 @@ def read_cmap(self, lines): for line in lst: entr = line.split() idx = [int(x) for x in entr[:5]] - + func = int(entr[5]) try: rest = ' '.join(entr[6:]) @@ -399,8 +399,8 @@ def read_cmap(self, lines): self.atoms[idx[3]-1],\ self.atoms[idx[4]-1],\ func,rest]) -# foo = (self.atoms[idx[0]-1],self.atoms[idx[1]-1],self.atoms[idx[2]-1],self.atoms[idx[3]-1],func,rest) -# print 'length %d' % len(foo) +# foo = (self.atoms[idx[0]-1],self.atoms[idx[1]-1],self.atoms[idx[2]-1],self.atoms[idx[3]-1],func,rest) +# print 'length %d' % len(foo) def read_exclusions(self, lines): starts = [] @@ -430,7 +430,7 @@ def read_vsites2(self, lines): for line in lst: entr = line.split() idx = [int(x) for x in entr[:3]] - + func = int(entr[3]) try: rest = ' '.join(entr[4:]) @@ -454,7 +454,7 @@ def read_vsites3(self, lines): for line in lst: entr = line.split() idx = [int(x) for x in entr[:4]] - + func = int(entr[4]) try: rest = ' '.join(entr[5:]) @@ -479,7 +479,7 @@ def read_vsites4(self, lines): for line in lst: entr = line.split() idx = [int(x) for x in entr[:5]] - + func = int(entr[5]) try: rest = ' '.join(entr[6:]) @@ -522,8 +522,8 @@ def read_posre(self, lstList): lst = lstList[lstKey] for line in lst: entr = line.split() - idx = int(entr[0]) - + idx = int(entr[0]) + func = int(entr[1]) try: rest = ' '.join(entr[2:]) @@ -562,7 +562,7 @@ def write(self, outfile, stateBonded = 'AB', stateTypes = 'AB', stateQ = 'AB', self.write_pairs(fp) self.write_angles(fp, state = stateBonded) self.write_dihedrals(fp, state = stateBonded) - self.write_cmap(fp) + self.write_cmap(fp) if self.has_vsites2: self.write_vsites2(fp) if self.has_vsites3: @@ -571,8 +571,8 @@ def write(self, outfile, stateBonded = 'AB', stateTypes = 'AB', stateQ = 'AB', self.write_vsites4(fp) if self.has_exclusions: self.write_exclusions(fp) - if self.has_posre: - self.write_posre(fp) + if self.has_posre: + self.write_posre(fp) if not is_out_itp: self.write_footer(fp) self.write_system(fp) @@ -585,19 +585,19 @@ def write(self, outfile, stateBonded = 'AB', stateTypes = 'AB', stateQ = 'AB', def write_header(self,fp): for line in self.header: - print >>fp, line + print(line, file=fp) def write_footer(self,fp): - try: + try: for line in self.footer: - print >>fp, line - except: - print "No footer in itp\n" + print(line, file=fp) + except: + print("No footer in itp\n") def write_moleculetype(self, fp): - print >>fp, '[ moleculetype ]' - print >>fp, '; Name nrexcl' - print >>fp, '%s %d' % (self.name,self.nrexcl) + print('[ moleculetype ]', file=fp) + print('; Name nrexcl', file=fp) + print('%s %d' % (self.name,self.nrexcl), file=fp) def write_atomtypes(self, fp): fp.write('[ atomtypes ]\n') @@ -659,8 +659,8 @@ def write_atoms(self, fp, charges = 'AB', atomtypes = 'AB', dummy_qA = 'on',\ else: atom.qqA = atom.q atom.qqB = atom.q - qA_tot = sum(map(lambda a: a.qqA, r.atoms)) - qB_tot = sum(map(lambda a: a.qqB, r.atoms)) + qA_tot = sum([a.qqA for a in r.atoms]) + qB_tot = sum([a.qqB for a in r.atoms]) if round(qB_tot,5) != round(target_chargeB,5): TR('State B has total charge of %g' % round(qB_tot,5)) TR('Applying charge correction to ensure integer charges') @@ -669,14 +669,14 @@ def write_atoms(self, fp, charges = 'AB', atomtypes = 'AB', dummy_qA = 'on',\ newqB = latom.qqB-(qB_tot-target_chargeB) TR('Changing chargeB of atom %s from %g to %g' % (latom.name, latom.qqB,newqB)) latom.qqB = newqB - qB_tot = sum(map(lambda a: a.qqB, r.atoms)) + qB_tot = sum([a.qqB for a in r.atoms]) TR('New total charge of B-state is %g' % round(qB_tot,5)) else: TR('No corrections applied to ensure integer charges') - print >>fp,'\n [ atoms ]' - print >>fp, '; nr type resnr residue atom cgnr charge mass typeB chargeB massB' + print('\n [ atoms ]', file=fp) + print('; nr type resnr residue atom cgnr charge mass typeB chargeB massB', file=fp) al = self.atoms for atom in al: if self.__atoms_morphe([atom]): @@ -710,15 +710,15 @@ def write_atoms(self, fp, charges = 'AB', atomtypes = 'AB', dummy_qA = 'on',\ else: qqA = atom.q qqB = atom.qB - print >>fp , '%6d %11s%7d%7s%7s%7d%11.6f%11.4f %11s%11.6f%11.4f' % \ + print('%6d %11s%7d%7s%7s%7d%11.6f%11.4f %11s%11.6f%11.4f' % \ (atom.id, atA, atom.resnr, atom.resname, atom.name, \ - atom.cgnr, qqA, mA, atB, qqB, mB) + atom.cgnr, qqA, mA, atB, qqB, mB), file=fp) self.qA+=qqA self.qB+=qqB else: - print >>fp , '%6d %11s%7d%7s%7s%7d%11.6f%11.4f' % \ + print('%6d %11s%7d%7s%7s%7d%11.6f%11.4f' % \ (atom.id, atom.atomtype, atom.resnr, atom.resname, atom.name, \ - atom.cgnr, atom.q, atom.m) + atom.cgnr, atom.q, atom.m), file=fp) self.qA+=atom.q self.qB+=atom.q # write qB of latom to qA @@ -731,142 +731,142 @@ def write_atoms(self, fp, charges = 'AB', atomtypes = 'AB', dummy_qA = 'on',\ def write_bonds(self,fp, state = 'AB'): - print >>fp,'\n [ bonds ]' - print >>fp, '; ai aj funct c0 c1 c2 c3' + print('\n [ bonds ]', file=fp) + print('; ai aj funct c0 c1 c2 c3', file=fp) for b in self.bonds: if len(b) == 3: - print >>fp, '%6d %6d %6d' % (b[0].id, b[1].id, b[2]) + print('%6d %6d %6d' % (b[0].id, b[1].id, b[2]), file=fp) elif len(b) == 4: s = ' '+' '.join([str(x) for x in b[3]]) - print >>fp, '%6d %6d %6d %s' % (b[0].id, b[1].id, b[2], s) + print('%6d %6d %6d %s' % (b[0].id, b[1].id, b[2], s), file=fp) else: lA = b[3][1] kA = b[3][2] lB = b[4][1] kB = b[4][2] if state == 'AB': - print >>fp, '%6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % \ - (b[0].id, b[1].id, b[2],lA,kA, lB, kB) + print('%6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % \ + (b[0].id, b[1].id, b[2],lA,kA, lB, kB), file=fp) elif state == 'AA': - print >>fp, '%6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % \ - (b[0].id, b[1].id, b[2],lA, kA, lA, kA) + print('%6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % \ + (b[0].id, b[1].id, b[2],lA, kA, lA, kA), file=fp) elif state == 'BB': - print >>fp, '%6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % \ - (b[0].id, b[1].id, b[2],lB, kB, lB, kB) + print('%6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % \ + (b[0].id, b[1].id, b[2],lB, kB, lB, kB), file=fp) def write_pairs(self, fp): # CHECK HOW THIS GOES WITH B-STATES - print >>fp,'\n [ pairs ]' - print >>fp, '; ai aj funct c0 c1 c2 c3' + print('\n [ pairs ]', file=fp) + print('; ai aj funct c0 c1 c2 c3', file=fp) for p in self.pairs: - print >>fp, '%6d %6d %6d' % (p[0].id, p[1].id, p[2]) + print('%6d %6d %6d' % (p[0].id, p[1].id, p[2]), file=fp) def write_constraints(self, fp): # CHECK HOW THIS GOES WITH B-STATES - print >>fp,'\n [ constraints ]' - print >>fp, '; ai aj funct c0 c1 c2 c3' + print('\n [ constraints ]', file=fp) + print('; ai aj funct c0 c1 c2 c3', file=fp) for p in self.constraints: - if(len(p)==3): - print >>fp, '%6d %6d %6d' % (p[0].id, p[1].id, p[2]) - else: - print >>fp, '%6d %6d %6d %8s' % (p[0].id, p[1].id, p[2], p[3]) + if(len(p)==3): + print('%6d %6d %6d' % (p[0].id, p[1].id, p[2]), file=fp) + else: + print('%6d %6d %6d %8s' % (p[0].id, p[1].id, p[2], p[3]), file=fp) def write_angles(self,fp, state='AB'): - print >>fp,'\n [ angles ]' - print >>fp, '; ai aj ak funct c0 c1 c2 c3' + print('\n [ angles ]', file=fp) + print('; ai aj ak funct c0 c1 c2 c3', file=fp) for ang in self.angles: if len(ang) == 4: - print >>fp, '%6d %6d %6d %6d' % (ang[0].id, ang[1].id, ang[2].id,ang[3]) + print('%6d %6d %6d %6d' % (ang[0].id, ang[1].id, ang[2].id,ang[3]), file=fp) else: if state == 'A': if ang[3]==1 : - print >>fp, '%6d %6d %6d %6d %14.6f %14.6f' % (ang[0].id, ang[1].id, ang[2].id,ang[3],ang[4][0],ang[4][1]) + print('%6d %6d %6d %6d %14.6f %14.6f' % (ang[0].id, ang[1].id, ang[2].id,ang[3],ang[4][0],ang[4][1]), file=fp) elif ang[3]==5 : - if shape(ang[4])[0]==4: - print >>fp, '%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % (ang[0].id, ang[1].id, ang[2].id,ang[3],ang[4][0],ang[4][1],ang[4][2],ang[4][3]) - else: - print >>fp, '%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % (ang[0].id, ang[1].id, ang[2].id,ang[3],ang[4][1],ang[4][2],ang[4][3],ang[4][4]) + if shape(ang[4])[0]==4: + print('%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % (ang[0].id, ang[1].id, ang[2].id,ang[3],ang[4][0],ang[4][1],ang[4][2],ang[4][3]), file=fp) + else: + print('%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % (ang[0].id, ang[1].id, ang[2].id,ang[3],ang[4][1],ang[4][2],ang[4][3],ang[4][4]), file=fp) else : - print "Don't know how to print angletype %d" % ang[3] + print("Don't know how to print angletype %d" % ang[3]) exit() if state == 'AB': -# print ang[0].id, ang[1].id, ang[2].id -# print state -# print ang - #MS check type here, for charmm its different, Urey-Bradley - if ang[3]==1 : +# print ang[0].id, ang[1].id, ang[2].id +# print state +# print ang + #MS check type here, for charmm its different, Urey-Bradley + if ang[3]==1 : # two possibilities: angle actually has a B-state or there is A state only if(len(ang)>5): # B-state exists - print >>fp, '%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ + print('%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ (ang[0].id, ang[1].id, ang[2].id,ang[3], ang[4][1], \ - ang[4][2], ang[5][1], ang[5][2], ang[0].name, ang[1].name, ang[2].name) + ang[4][2], ang[5][1], ang[5][2], ang[0].name, ang[1].name, ang[2].name), file=fp) else: # A-state only - print >>fp, '%6d %6d %6d %6d %14.6f %14.6f' % (ang[0].id, ang[1].id, ang[2].id,ang[3], ang[4][0], ang[4][1]) - - elif ang[3]==5: + print('%6d %6d %6d %6d %14.6f %14.6f' % (ang[0].id, ang[1].id, ang[2].id,ang[3], ang[4][0], ang[4][1]), file=fp) + + elif ang[3]==5: # two possibilities: angle actually has a B-state or there is A state only if(len(ang)>5): # B-state exists - print >>fp, '%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ + print('%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ (ang[0].id, ang[1].id, ang[2].id,ang[3], ang[4][1], \ ang[4][2], ang[4][3], ang[4][4], ang[5][1], \ - ang[5][2], ang[5][3], ang[5][4], \ - ang[0].name, ang[1].name, ang[2].name) + ang[5][2], ang[5][3], ang[5][4], \ + ang[0].name, ang[1].name, ang[2].name), file=fp) else: # A-state only - print >>fp, '%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % (ang[0].id, ang[1].id, ang[2].id,ang[3], ang[4][1],ang[4][2], ang[4][3], ang[4][4] ) - else : - print "Don't know how to print angletype %d" % ang[3] - exit() + print('%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f' % (ang[0].id, ang[1].id, ang[2].id,ang[3], ang[4][1],ang[4][2], ang[4][3], ang[4][4] ), file=fp) + else : + print("Don't know how to print angletype %d" % ang[3]) + exit() elif state == 'AA': - if ang[3]==1 : - print >>fp, '%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ + if ang[3]==1 : + print('%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ (ang[0].id, ang[1].id, ang[2].id,ang[3], ang[4][1], \ - ang[4][2], ang[4][1], ang[4][2], ang[0].name, ang[1].name, ang[2].name) - elif ang[3]==5: - print >>fp, '%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ + ang[4][2], ang[4][1], ang[4][2], ang[0].name, ang[1].name, ang[2].name), file=fp) + elif ang[3]==5: + print('%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ (ang[0].id, ang[1].id, ang[2].id,ang[3], ang[4][1], \ ang[4][2], ang[4][3], ang[4][4], ang[4][1], \ - ang[4][2], ang[4][3], ang[4][4], \ - ang[0].name, ang[1].name, ang[2].name) - else : - print "Don't know how to print angletype %d" % ang[3] - exit() + ang[4][2], ang[4][3], ang[4][4], \ + ang[0].name, ang[1].name, ang[2].name), file=fp) + else : + print("Don't know how to print angletype %d" % ang[3]) + exit() elif state == 'BB': - if ang[3]==1 : - print >>fp, '%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ + if ang[3]==1 : + print('%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ (ang[0].id, ang[1].id, ang[2].id,ang[3], ang[5][1], \ - ang[5][2], ang[5][1], ang[5][2], ang[0].name, ang[1].name, ang[2].name) - elif ang[3]==5: - print >>fp, '%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ + ang[5][2], ang[5][1], ang[5][2], ang[0].name, ang[1].name, ang[2].name), file=fp) + elif ang[3]==5: + print('%6d %6d %6d %6d %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f %14.6f ; %s %s %s' % \ (ang[0].id, ang[1].id, ang[2].id,ang[3], ang[5][1], \ ang[5][2], ang[5][3], ang[5][4], ang[5][1], \ - ang[5][2], ang[5][3], ang[5][4], \ - ang[0].name, ang[1].name, ang[2].name) - else : - print "Don't know how to print angletype %d" % ang[3] - exit() + ang[5][2], ang[5][3], ang[5][4], \ + ang[0].name, ang[1].name, ang[2].name), file=fp) + else : + print("Don't know how to print angletype %d" % ang[3]) + exit() def write_cmap(self, fp): - print >>fp,'\n [ cmap ]' - print >>fp,'; ai aj ak al am funct' + print('\n [ cmap ]', file=fp) + print('; ai aj ak al am funct', file=fp) for d in self.cmap: - print >>fp, "%6d %6d %6d %6d %6d %4d" % ( d[0].id, d[1].id, d[2].id,d[3].id,d[4].id,d[5]) + print("%6d %6d %6d %6d %6d %4d" % ( d[0].id, d[1].id, d[2].id,d[3].id,d[4].id,d[5]), file=fp) def write_dihedrals(self, fp, state='AB'): - print >>fp,'\n [ dihedrals ]' - print >>fp,'; ai aj ak al funct c0 c1 c2 c3 c4 c5' + print('\n [ dihedrals ]', file=fp) + print('; ai aj ak al funct c0 c1 c2 c3 c4 c5', file=fp) for d in self.dihedrals: if len(d) == 5: - print >>fp, "%6d %6d %6d %6d %4d" % ( d[0].id, d[1].id, d[2].id, d[3].id, d[4]) + print("%6d %6d %6d %6d %4d" % ( d[0].id, d[1].id, d[2].id, d[3].id, d[4]), file=fp) elif len(d) == 6: - print >>fp, "%6d %6d %6d %6d %4d %s" % ( d[0].id, d[1].id, d[2].id, d[3].id, d[4], d[5]) + print("%6d %6d %6d %6d %4d %s" % ( d[0].id, d[1].id, d[2].id, d[3].id, d[4], d[5]), file=fp) elif len(d) == 7: A, B = self.__check_case(d[:4]) ast = d[5] bs = d[6] if ast == None or bs == None: - print d[0].name, d[1].name, d[2].name, d[3].name, d[0].atomtype, d[1].atomtype, d[2].atomtype, d[3].atomtype, d[0].atomtypeB, d[1].atomtypeB, d[2].atomtypeB, d[3].atomtypeB - print d[0].type, d[1].type, d[2].type, d[3].type, d[0].typeB, d[1].typeB, d[2].typeB, d[3].typeB + print(d[0].name, d[1].name, d[2].name, d[3].name, d[0].atomtype, d[1].atomtype, d[2].atomtype, d[3].atomtype, d[0].atomtypeB, d[1].atomtypeB, d[2].atomtypeB, d[3].atomtypeB) + print(d[0].type, d[1].type, d[2].type, d[3].type, d[0].typeB, d[1].typeB, d[2].typeB, d[3].typeB) if ast == 'NULL': if d[4] == 3: # Ryckaert-Bellemans ast = ' '.join(["%g" % x for x in [0,0,0,0,0,0]]) @@ -876,147 +876,147 @@ def write_dihedrals(self, fp, state='AB'): ast = ' '.join(["%g" % x for x in [0,0,0]]) elif d[4] == 2: ast = ' '.join(["%g" % x for x in [0,0]]) - + elif ast != 'NULL' and hasattr(ast,"append"): ast = ' '.join(["%.10g" % x for x in d[5][1:]]) if bs == 'NULL': if d[4] == 3: - bs = ' '.join(["%g" % x for x in [0,0,0,0,0,0]]) + bs = ' '.join(["%g" % x for x in [0,0,0,0,0,0]]) elif d[4] == 1 or d[4] == 4: bs = ' '.join(["%g" % x for x in [0,0,0]]) elif d[4] == 9: bs = ' '.join(["%g" % x for x in [0,0,0]]) elif d[4] == 2: bs = ' '.join(["%g" % x for x in [0,0]]) - + elif bs !='NULL' and hasattr(bs,"append"): bs = ' '.join(["%.10g" % x for x in d[6][1:]]) if state == 'AB': - print >>fp, "%6d %6d %6d %6d %4d %s %s ; %s %s %s %s %s %s %s %s (%s->%s)" % \ + print("%6d %6d %6d %6d %4d %s %s ; %s %s %s %s %s %s %s %s (%s->%s)" % \ ( d[0].id, d[1].id, d[2].id, d[3].id, d[4], ast, bs, d[0].name,d[1].name,d[2].name,d[3].name, \ - d[0].type,d[1].type,d[2].type,d[3].type,A,B) + d[0].type,d[1].type,d[2].type,d[3].type,A,B), file=fp) elif state == 'AA': - print >>fp, "%6d %6d %6d %6d %4d %s %s ; %s %s %s %s %s %s %s %s (%s->%s)" % \ + print("%6d %6d %6d %6d %4d %s %s ; %s %s %s %s %s %s %s %s (%s->%s)" % \ ( d[0].id, d[1].id, d[2].id, d[3].id, d[4], ast, ast, d[0].name,d[1].name,d[2].name,d[3].name, \ - d[0].type,d[1].type,d[2].type,d[3].type, A,B) + d[0].type,d[1].type,d[2].type,d[3].type, A,B), file=fp) elif state == 'BB': - print >>fp, "%6d %6d %6d %6d %4d %s %s ; %s %s %s %s %s %s %s %s (%s->%s)" % \ + print("%6d %6d %6d %6d %4d %s %s ; %s %s %s %s %s %s %s %s (%s->%s)" % \ ( d[0].id, d[1].id, d[2].id, d[3].id, d[4], bs, bs, d[0].name,d[1].name,d[2].name,d[3].name, \ - d[0].type,d[1].type,d[2].type,d[3].type, A,B) + d[0].type,d[1].type,d[2].type,d[3].type, A,B), file=fp) def write_exclusions(self, fp): - print >>fp,'\n [ exclusions ]' + print('\n [ exclusions ]', file=fp) for excl in self.exclusions: towrite = '' for ex in excl: towrite += ' '+str(ex.id) - print >>fp, "%s" % towrite + print("%s" % towrite, file=fp) def write_vsites2(self, fp): - print >>fp,'\n [ virtual_sites2 ]' - print >>fp,'; ai aj ak funct c0 c1' + print('\n [ virtual_sites2 ]', file=fp) + print('; ai aj ak funct c0 c1', file=fp) for vs in self.virtual_sites2: if len(vs) == 4: - print >>fp, "%6d %6d %6d %4d" % ( vs[0].id, vs[1].id, vs[2].id, vs[3]) + print("%6d %6d %6d %4d" % ( vs[0].id, vs[1].id, vs[2].id, vs[3]), file=fp) elif len(vs) == 5: - print >>fp, "%6d %6d %6d %4d %s" % ( vs[0].id, vs[1].id, vs[2].id, vs[3], vs[4]) + print("%6d %6d %6d %4d %s" % ( vs[0].id, vs[1].id, vs[2].id, vs[3], vs[4]), file=fp) else: sys.stderr.write('EEK! Something went wrong while writing virtual_sites2!!!!\n') - print vs + print(vs) sys.exit(1) def write_vsites3(self, fp): - print >>fp,'\n [ virtual_sites3 ]' - print >>fp,'; ai aj ak al funct c0 c1' + print('\n [ virtual_sites3 ]', file=fp) + print('; ai aj ak al funct c0 c1', file=fp) for vs in self.virtual_sites3: if len(vs) == 5: - print >>fp, "%6d %6d %6d %6d %4d" % ( vs[0].id, vs[1].id, vs[2].id, vs[3].id, vs[4]) + print("%6d %6d %6d %6d %4d" % ( vs[0].id, vs[1].id, vs[2].id, vs[3].id, vs[4]), file=fp) elif len(vs) == 6: - print >>fp, "%6d %6d %6d %6d %4d %s" % ( vs[0].id, vs[1].id, vs[2].id, vs[3].id, vs[4], vs[5]) + print("%6d %6d %6d %6d %4d %s" % ( vs[0].id, vs[1].id, vs[2].id, vs[3].id, vs[4], vs[5]), file=fp) else: sys.stderr.write('EEK! Something went wrong while writing virtual_sites3!!!!\n') - print vs + print(vs) sys.exit(1) def write_vsites4(self, fp): - print >>fp,'\n [ virtual_sites4 ]' - print >>fp,'; ai aj ak al am funct c0 c1 c2' + print('\n [ virtual_sites4 ]', file=fp) + print('; ai aj ak al am funct c0 c1 c2', file=fp) for vs in self.virtual_sites4: if len(vs) == 6: - print >>fp, "%6d %6d %6d %6d %6d %4d" % ( vs[0].id, vs[1].id, vs[2].id, vs[3].id, vs[4].id, vs[5]) + print("%6d %6d %6d %6d %6d %4d" % ( vs[0].id, vs[1].id, vs[2].id, vs[3].id, vs[4].id, vs[5]), file=fp) elif len(vs) == 7: - print >>fp, "%6d %6d %6d %6d %6d %4d %s" % ( vs[0].id, vs[1].id, vs[2].id, vs[3].id, vs[4].id, vs[5], vs[6]) + print("%6d %6d %6d %6d %6d %4d %s" % ( vs[0].id, vs[1].id, vs[2].id, vs[3].id, vs[4].id, vs[5], vs[6]), file=fp) else: sys.stderr.write('EEK! Something went wrong while writing virtual_sites4!!!!\n') - print vs + print(vs) sys.exit(1) def write_posre(self, fp): - print >>fp,'\n [ position_restraints ]' - print >>fp,'; ai funct c0 c1 c2' + print('\n [ position_restraints ]', file=fp) + print('; ai funct c0 c1 c2', file=fp) for pr in self.posre: if len(pr) == 3: - print >>fp, "%6d %4d %s" % ( pr[0].id, pr[1], pr[2]) + print("%6d %4d %s" % ( pr[0].id, pr[1], pr[2]), file=fp) else: sys.stderr.write('EEK! Something went wrong while writing position_restraints!!!!\n') - print pr + print(pr) sys.exit(1) def write_ii(self, fp): fp.write('\n [ intermolecular_interactions ]\n') # bonds - if 'bonds' in self.ii.keys(): - fp.write(' [ bonds ]\n') - for b in self.ii['bonds']: - fp.write('%6d %6d %6d' % ( b[0].id, b[1].id, b[2] )) - if len(b)>3: - for x in b[3]: - fp.write(' %14.6f' % x) - fp.write('\n') + if 'bonds' in list(self.ii.keys()): + fp.write(' [ bonds ]\n') + for b in self.ii['bonds']: + fp.write('%6d %6d %6d' % ( b[0].id, b[1].id, b[2] )) + if len(b)>3: + for x in b[3]: + fp.write(' %14.6f' % x) + fp.write('\n') # angles - if 'angles' in self.ii.keys(): - fp.write(' [ angles ]\n') - for ang in self.ii['angles']: - fp.write('%6d %6d %6d %6d' % ( ang[0].id, ang[1].id, ang[2].id, ang[3] )) - if len(ang)>4: - for x in ang[4]: - fp.write(' %14.6f' % x) - fp.write('\n') + if 'angles' in list(self.ii.keys()): + fp.write(' [ angles ]\n') + for ang in self.ii['angles']: + fp.write('%6d %6d %6d %6d' % ( ang[0].id, ang[1].id, ang[2].id, ang[3] )) + if len(ang)>4: + for x in ang[4]: + fp.write(' %14.6f' % x) + fp.write('\n') # dihedrals - if 'dihedrals' in self.ii.keys(): - fp.write(' [ dihedrals ]\n') - for dih in self.ii['dihedrals']: - fp.write('%6d %6d %6d %6d %6d' % ( dih[0].id, dih[1].id, dih[2].id, dih[3].id, dih[4] )) - if len(dih)>5: - for x in dih[5]: - fp.write(' %14.6f' % x) - fp.write('\n') + if 'dihedrals' in list(self.ii.keys()): + fp.write(' [ dihedrals ]\n') + for dih in self.ii['dihedrals']: + fp.write('%6d %6d %6d %6d %6d' % ( dih[0].id, dih[1].id, dih[2].id, dih[3].id, dih[4] )) + if len(dih)>5: + for x in dih[5]: + fp.write(' %14.6f' % x) + fp.write('\n') def write_system(self,fp): - print >>fp, '[ system ]' - print >>fp, self.system + print('[ system ]', file=fp) + print(self.system, file=fp) def write_molecules(self,fp): - print >>fp, '[ molecules ]' + print('[ molecules ]', file=fp) for mol, num in self.molecules: - print >>fp, "%s %d" % (mol,num) + print("%s %d" % (mol,num), file=fp) #==================================================================================== # other functions def __check_case(self, atoms): - A = '' - B = '' - for a in atoms: - if a.atomtype.startswith('DUM'): A += 'D' - else: A += 'A' - if a.atomtypeB is not None: - if a.atomtypeB.startswith('DUM'): B += 'D' - else: B += 'A' + A = '' + B = '' + for a in atoms: + if a.atomtype.startswith('DUM'): A += 'D' + else: A += 'A' + if a.atomtypeB is not None: + if a.atomtypeB.startswith('DUM'): B += 'D' else: B += 'A' - return A, B + else: B += 'A' + return A, B def __atoms_morphe( self, atoms ): @@ -1028,11 +1028,11 @@ def __atomtypes_morphe(self, atoms): for atom in atoms: if atom.atomtypeB is not None and atom.atomtype != atom.atomtypeB: return True return False - + def __is_perturbed_residue( self, residue ): if self.__atoms_morphe(residue.atoms): return True return False - + def __last_perturbed_atom(self, r): max_order = 0 @@ -1042,7 +1042,7 @@ def __last_perturbed_atom(self, r): if not atom.atomtype.startswith('DUM') and not atom.atomtypeB.startswith('DUM'): last_atom = atom if last_atom == None: - print >>sys.stderr, 'Error: Could not find a perturbed atom to put rest charges on !' + print('Error: Could not find a perturbed atom to put rest charges on !', file=sys.stderr) sys.exit(1) return last_atom @@ -1078,10 +1078,10 @@ class Topology( TopolBase ): # def __init__(self, filename, topfile = None, assign_types = True, cpp_path = [os.environ.get('GMXDATA')+'/top'], cpp_defs = [], version = 'old', ff = 'amber' ): def __init__(self, filename, topfile = None, assign_types = True, cpp_path = [os.environ.get('GMXLIB')], cpp_defs = [], version = 'old', ff = 'amber', ffpath=None ): TopolBase.__init__(self, filename, version) - bItp = False + bItp = False if not topfile: topfile = filename - bItp = True + bItp = True if assign_types: l = cpp_parse_file(topfile, cpp_defs = cpp_defs, cpp_path = cpp_path, itp = bItp, ffpath = ffpath) l = kickOutComments(l,'#') @@ -1099,7 +1099,7 @@ def set_molecule(self, molname, n): mol_exists = True if not mol_exists: self.molecules.append([molname,n]) - + def del_molecule(self, molname): if not hasattr(molname,"append"): molname = [molname] @@ -1117,13 +1117,13 @@ def assign_fftypes(self): atom.typeB = self.NBParams.atomtypes[atom.atomtypeB]['bond_type'] else: atom.typeB = atom.type - + def make_bond_params(self): for i, (at1,at2,func) in enumerate(self.bonds): param = self.BondedParams.get_bond_param(at1.type,at2.type) if param is None: - print 'Error! No bonded parameters found! (%s-%s)' % \ - (at1.type, at2.type) + print('Error! No bonded parameters found! (%s-%s)' % \ + (at1.type, at2.type)) sys.exit(1) self.bonds[i].append(param[1:]) @@ -1131,11 +1131,11 @@ def make_angle_params(self): for i, (at1, at2, at3, func) in enumerate(self.angles): param = self.BondedParams.get_angle_param(at1.type, at2.type, at3.type) if param is None: - print 'Error! No angle parameters found! (%s-%s-%s)' % \ - (at1.type, at2.type, at3.type) + print('Error! No angle parameters found! (%s-%s-%s)' % \ + (at1.type, at2.type, at3.type)) sys.exit(1) self.angles[i].append(param[1:]) - + def make_dihedral_params(self): for i, d in enumerate(self.dihedrals): if d[5]!='': # we have a prefefined dihedral @@ -1146,16 +1146,16 @@ def make_dihedral_params(self): at3.type, at4.type, \ func) if param is None: - print 'Error! No dihedral parameters found! (%s-%s-%s-%s)' % \ - (at1.type, at2.type, at3.type, at4.type) - print func, dih + print('Error! No dihedral parameters found! (%s-%s-%s-%s)' % \ + (at1.type, at2.type, at3.type, at4.type)) + print(func, dih) sys.exit(1) del self.dihedrals[i][-1] self.dihedrals[i].append(param[1:]) #================================================================================= - + class GAFFTopology( TopolBase ): def __init__(self, filename): @@ -1173,11 +1173,11 @@ def set_name( self, name ): self.name = name for atom in self.atoms: atom.name = name - + #================================================================================= - - + + class MDPError(Exception): def __init__(self, s): self.s = s @@ -1185,7 +1185,7 @@ def __str__(self): return repr(self.s) #================================================================================= - + class MDP: def __init__(self): @@ -1354,7 +1354,7 @@ def __init__(self): def __str__(self): line = '' - for key, val in self.parameters.items(): + for key, val in list(self.parameters.items()): if hasattr(val,"append"): s = '' for x in val: @@ -1363,13 +1363,13 @@ def __str__(self): s = str(val) line+="%-25s = %s\n" % (key, s) return line - + def __setitem__(self,item,value): - if not self.parameters.has_key(item): - raise MDPError, "No such option %s" % item - + if item not in self.parameters: + raise MDPError("No such option %s" % item) + self.parameters[item] = value - + def write(self, fp = None): if fp is None: @@ -1377,7 +1377,7 @@ def write(self, fp = None): else: if not hasattr(fp,"write"): fp = open(fp,"w") - print >>fp, self + print(self, file=fp) def read(self, filename): lines = open(filename).readlines() @@ -1386,8 +1386,8 @@ def read(self, filename): entr = line.split('=') key = entr[0].strip() val = entr[1].strip().split() - if not self.parameters.has_key(key): - print 'Warning! Ignoring entry \'%s\'' % key + if key not in self.parameters: + print('Warning! Ignoring entry \'%s\'' % key) else: if len(val) == 0: self[key] = '' @@ -1424,7 +1424,7 @@ def make_amber_residue_names(model): res.set_resname(rr) else: res.set_resname('CYM') - + else: res.set_resname('CYN') lysl = model.fetch_residues('LYS') @@ -1483,7 +1483,7 @@ def make_amber_residue_names(model): o1.name = 'OC1' o2.name = 'OC2' except: - print >>sys.stderr, 'pmx_Warning_> No terminal oxygen atoms found in chain %s' % chain.id + print('pmx_Warning_> No terminal oxygen atoms found in chain %s' % chain.id, file=sys.stderr) #================================================================================= @@ -1493,7 +1493,7 @@ def assign_ffamber99sb_params(m): m.rename_atoms() for c in m.chains: c.make_residue_tree() - + make_amber_residue_names( m) rtp = RTPParser('ffamber99sb.rtp') rtp.assign_params(m) @@ -1502,7 +1502,7 @@ def assign_ffamber99sb_params(m): nb.assign_params( m ) bo.assign_params( m ) rtp.assign_dihedral_params( m, bo.directives ) - + #================================================================================= @@ -1528,7 +1528,7 @@ def nb_energy( m ): def energy(m): - bond_ene = bond_energy( m ) + bond_ene = bond_energy( m ) angle_ene = angle_energy( m ) dihedral_ene = dihedral_energy( m ) improper_ene = improper_energy ( m ) @@ -1536,6 +1536,3 @@ def energy(m): coul14_ene = coul14_energy( m ) nb_ene = nb_energy( m ) return bond_ene + angle_ene + dihedral_ene + improper_ene + nb_ene + lj14_ene + coul14_ene - - - diff --git a/pmx/futil.py b/pmx/futil.py index c8e71a44..f7230dce 100644 --- a/pmx/futil.py +++ b/pmx/futil.py @@ -43,30 +43,30 @@ def ffopen(filename,mode='r',backup = True): if mode == 'w': if os.path.isfile(filename): if backup: - print 'Backing up %s to %s~' % (filename,filename) + print('Backing up %s to %s~' % (filename,filename)) os.rename(filename,filename+'~') try: fp = open(filename,'w') return fp except: - print 'Error: Could not open file %s' % filename - + print('Error: Could not open file %s' % filename) + elif mode == 'r': try: fp = open(filename,'r') return fp except: - print 'No such file %s' % filename + print('No such file %s' % filename) else: return open(filename,mode) - + #========================================= def listFiles(dir='./',ext=None,abs=True,\ backups = False): - + """ returns a list of files in directory dir, optionally only certain file types""" @@ -89,9 +89,9 @@ def listFiles(dir='./',ext=None,abs=True,\ fl.append(dir+f) else: fl.append(dir+f) - - elif type(ext) in [types.ListType,\ - types.TupleType]: + + elif type(ext) in [list,\ + tuple]: for ex in ext: if backups: ff = glob(dir+'#*'+ex+'*') @@ -100,9 +100,9 @@ def listFiles(dir='./',ext=None,abs=True,\ ff = glob(dir+'*.'+ex) fl.extend(ff) - elif type(ext) == types.StringType: + elif type(ext) == bytes: if backups: - print dir+'*.'+ext+'~' + print(dir+'*.'+ext+'~') fl = glob(dir+'#*.'+ext+'*') fl+= glob(dir+'*.'+ext+'~') else: @@ -113,10 +113,10 @@ def listFiles(dir='./',ext=None,abs=True,\ for f in fl: new.append(f.split('/')[-1]) return new - + return fl - - + + #========================================= def listDirs(dir='./'): @@ -138,8 +138,8 @@ def listDirs(dir='./'): dl.append(dir+f) return dl - - + + #========================================= def killBackups(arg,dirname,fname): @@ -147,14 +147,14 @@ def killBackups(arg,dirname,fname): l = listFiles(dirname,arg[0],arg[1],arg[2]) if arg[3]: for f in l: - print '%s' % f + print('%s' % f) # print 'dir:', dirname # print 'fname' ,fname #========================================= def removeBackups(dir,check=True): - + if dir[-1]!=os.sep: dir+=os.sep if dir[0]=='~': home = os.environ.get('HOME') @@ -162,6 +162,3 @@ def removeBackups(dir,check=True): dir = os.path.abspath(dir)+os.sep os.path.walk(dir,killBackups,(False,True,True,check)) - - - diff --git a/pmx/geometry.py b/pmx/geometry.py index dac57e13..c1933ac4 100644 --- a/pmx/geometry.py +++ b/pmx/geometry.py @@ -36,20 +36,20 @@ >>> r = Rotation(v1,v2) # create rotation object around v2-v1 >>> v3 = [4,5,6] >>> v3 = r.apply(v3) # rotate v3 around v2-v1 - - + + """ from numpy import * -from atom import Atom -import _pmx as _p +from .atom import Atom +from . import _pmx as _p class Rotation2: def __init__(self,v1,v2): """ creates a rotation object around the vector v2-v1""" - + self.v1 = array(v1) self.v2 = array(v2) tmp = array(v2) @@ -65,11 +65,11 @@ def __rm1(self): a = self.norm_vec self.m1 = matrix( [ - [ a[0]*a[0], a[0]*a[1], a[0]*a[2]], - [ a[1]*a[0], a[1]*a[1], a[1]*a[2]], - [ a[2]*a[0], a[2]*a[1], a[2]*a[2]] + [ a[0]*a[0], a[0]*a[1], a[0]*a[2]], + [ a[1]*a[0], a[1]*a[1], a[1]*a[2]], + [ a[2]*a[0], a[2]*a[1], a[2]*a[2]] ] ) - + def __rm2(self): a = self.norm_vec @@ -97,7 +97,7 @@ class Rotation: def __init__(self,v1,v2): """ creates a rotation object around the vector v2-v1""" - + self.v1 = array(v1) # self.v2 = array(v2) self.v2 = [v2[0], v2[1], v2[2]] #array(v2) @@ -114,11 +114,11 @@ def __rm1(self): a = self.norm_vec self.m1 = [ - [ a[0]*a[0], a[0]*a[1], a[0]*a[2]], - [ a[1]*a[0], a[1]*a[1], a[1]*a[2]], - [ a[2]*a[0], a[2]*a[1], a[2]*a[2]] - ] - + [ a[0]*a[0], a[0]*a[1], a[0]*a[2]], + [ a[1]*a[0], a[1]*a[1], a[1]*a[2]], + [ a[2]*a[0], a[2]*a[1], a[2]*a[2]] + ] + def __rm2(self): a = self.norm_vec @@ -126,14 +126,14 @@ def __rm2(self): [ 0.0, -a[2], a[1]], [ a[2], 0.0, -a[0]], [ -a[1], a[0], 0.0] - ] + ] def apply(self,v, phi): return _p.apply_rotation( self, [v[0], v[1], v[2]], phi) - + def vec_ang(v1,v2): x1 = linalg.norm(v1) x2 = linalg.norm(v2) @@ -165,7 +165,7 @@ def bb_super(mol1,mol2, use_orig_mc_coords = True): atoms2 = mol2.fetchm(gly_atom_set) else: atoms2 = mol2.fetchm(atom_set) - assert len(atoms1) == len(atoms2), "%s -> %s" % ( '-'.join( map(lambda a: a.name, atoms1)),'-'.join( map(lambda a: a.name, atoms2)) ) + assert len(atoms1) == len(atoms2), "%s -> %s" % ( '-'.join( [a.name for a in atoms1]),'-'.join( [a.name for a in atoms2]) ) for atom1, atom2 in zip(atoms1, atoms2): atom2.x = atom1.x @@ -173,9 +173,9 @@ def nuc_super(mol1,mol2,name1=None,name2=None): """ superpose mol2 on mol1""" if name1==None: - name1 = mol1.resname[:2] + name1 = mol1.resname[:2] if name2==None: - name2 = mol2.resname[:2] + name2 = mol2.resname[:2] if name1 in ['DT','DC','RC','RU']: fit1_atoms = ['C1\'', 'C6','N1','C2','C5','N3'] @@ -238,14 +238,14 @@ def nuc_super(mol1,mol2,name1=None,name2=None): def planarity(atom_list): - coords = map(lambda a: a.x, atom_list) + coords = [a.x for a in atom_list] plan = _p.planarity(coords) return plan def apply_fit_R( atoms, R): - + for atom in atoms: - x_old = map(lambda x: x, atom.x) + x_old = [x for x in atom.x] for r in range(3): atom.x[r] = 0 for c in range(3): @@ -264,14 +264,14 @@ def fit(model1, model2, atom_names = []): if atom_names: subset1 = model1.fetch_atoms( atom_names ) subset2 = model2.fetch_atoms( atom_names ) - cs1 = map(lambda a: a.x, subset1) - cs2 = map(lambda a: a.x, subset2) + cs1 = [a.x for a in subset1] + cs2 = [a.x for a in subset2] else: cs1 = model1.coords() cs2 = model2.coords() assert( len(cs1) == len(cs2) ) - m = map(lambda x: 1., cs1) # dummy array + m = [1. for x in cs1] # dummy array v = _p.center_vec( cs1 ) v2 = _p.center_vec( cs2 ) R = _p.calc_fit_R(cs1, cs2, m) @@ -281,11 +281,11 @@ def fit(model1, model2, atom_names = []): def fit_by_ndx(ref, model, ndx1, ndx2): - crd1 = map(lambda i: ref.atoms[i-1].x, ndx1) - crd2 = map(lambda i: model.atoms[i-1].x, ndx2) - + crd1 = [ref.atoms[i-1].x for i in ndx1] + crd2 = [model.atoms[i-1].x for i in ndx2] + assert( len(crd1) == len(crd2) ) - m = map(lambda x: 1., crd1) # dummy array + m = [1. for x in crd1] # dummy array v = _p.center_vec( crd1 ) v2 = _p.center_vec( crd2 ) R = _p.calc_fit_R(crd1, crd2, m) @@ -294,18 +294,18 @@ def fit_by_ndx(ref, model, ndx1, ndx2): model.translate( v ) def translate_by_ndx(struct, ndx): - crd = map(lambda i: struct.atoms[i-1].x, ndx) - m = map(lambda x: 1., crd) + crd = [struct.atoms[i-1].x for i in ndx] + m = [1. for x in crd] v = _p.center_vec( crd ) struct.translate( [-v[0], -v[1], -v[2]] ) return(v) def fit_atoms( fit_atoms1, fit_atoms2, rot_atoms2 ): - cs1 = map(lambda a: a.x, fit_atoms1) - cs2 = map(lambda a: a.x, fit_atoms2) + cs1 = [a.x for a in fit_atoms1] + cs2 = [a.x for a in fit_atoms2] assert len(cs1) == len(cs2) - m = map(lambda x: 1., cs1) # dummy array + m = [1. for x in cs1] # dummy array v = _p.center_vec( cs1 ) v2 = _p.center_vec( cs2 ) R = _p.calc_fit_R(cs1, cs2, m) @@ -318,7 +318,3 @@ def fit_atoms( fit_atoms1, fit_atoms2, rot_atoms2 ): atom.x[0]+=v[0] atom.x[1]+=v[1] atom.x[2]+=v[2] - - - - diff --git a/pmx/histogram.py b/pmx/histogram.py index 9adf8452..e0b0cca1 100644 --- a/pmx/histogram.py +++ b/pmx/histogram.py @@ -37,7 +37,7 @@ class Histogram: """ class to store data as histogram """ - + def __init__(self,begin,end,incr): """ initialize histogram (start, end, increment)""" self.values=arange(begin,end,incr) @@ -56,7 +56,7 @@ def add(self,x,weight=1.): x min_val: list.append(self.counter[value]) x.append( value) - + return trapz(list,x=x) - + def mean(self): """ calculate the mean value""" @@ -130,19 +130,16 @@ def stddev(self): if __name__=='__main__': - print 'testing histogram' + print('testing histogram') h = Histogram(0,10,1) import random for i in range(1000): n = random.randint(0,10) h.add(n) - print 'mean = ', h.mean() - print 'stdev = ', h.stddev() - print 'var = ', h.variance() - print 'integ = ', h.integ() - print 'norming histogram....' + print('mean = ', h.mean()) + print('stdev = ', h.stddev()) + print('var = ', h.variance()) + print('integ = ', h.integ()) + print('norming histogram....') h.norm() - print 'new integral', h.integ() - - - + print('new integral', h.integ()) diff --git a/pmx/library.py b/pmx/library.py index 5188279e..c26730ab 100644 --- a/pmx/library.py +++ b/pmx/library.py @@ -31,7 +31,7 @@ Library for useful and less useful things needed by the pmx packages. """ -import sys, os, cPickle +import sys, os, pickle #pdb_format="%6s%5d %-4s%1s%3s%2s%4d %11.3f %7.3f %7.3f %5.2f %5.2f\n" @@ -51,13 +51,13 @@ def pmx_data_file( filename ): pth = PMX_DATA data_file = os.path.join(pth,filename) if not os.path.isfile(data_file): - print >>sys.stderr, "pmx_ERROR> data file \"%s\" not found " % data_file + print("pmx_ERROR> data file \"%s\" not found " % data_file, file=sys.stderr) sys.exit(1) - print >>sys.stderr,"pmx__> Loading data file \"%s\"" % data_file + print("pmx__> Loading data file \"%s\"" % data_file, file=sys.stderr) if data_file.split('.')[-1] == 'pkl': - return cPickle.load(open(data_file)) + return pickle.load(open(data_file, 'rb')) else: return data_file - + _aacids_dic = { @@ -349,7 +349,7 @@ def pmx_data_file( filename ): 'Se' : 78.96, 'SE' : 78.96, 'Br' : 79.904, - 'BR' : 79.904, + 'BR' : 79.904, 'Kr' : 83.80, 'KR' : 83.80, 'Rb' : 85.4678, @@ -513,8 +513,8 @@ def pmx_data_file( filename ): _aacids = { - - 'ALA' : + + 'ALA' : ( ('N', [ -2.983, -4.446, 6.956 ]), ('H', [ -3.447, -5.331, 7.094 ]), @@ -527,7 +527,7 @@ def pmx_data_file( filename ): ('C', [ -1.219, -2.972, 7.862 ]), ('O', [ -1.895, -2.016, 7.478 ]) ), - 'ARG' : + 'ARG' : ( ('N', [ -0.095, -2.820, 8.564 ]), ('H', [ 0.440, -3.638, 8.837 ]), @@ -554,7 +554,7 @@ def pmx_data_file( filename ): ('C', [ 1.922, -1.920, 9.531 ]), ('O', [ 2.133, -3.070, 9.916 ]) ), - 'ASP' : + 'ASP' : ( ('N', [ 2.810, -0.929, 9.643 ]), ('H', [ 2.577, 0.002, 9.335 ]), @@ -569,7 +569,7 @@ def pmx_data_file( filename ): ('C', [ 4.529, 0.498, 10.585 ]), ('O', [ 3.960, 1.407, 9.962 ]) ), - 'ASH' : + 'ASH' : ( ('N', [ 2.810, -0.929, 9.643 ]), ('H', [ 2.577, 0.002, 9.335 ]), @@ -602,7 +602,7 @@ def pmx_data_file( filename ): ('C', [ 7.478, 1.762, 12.495 ]), ('O', [ 7.772, 0.654, 12.925 ]) ), - 'CYS' : + 'CYS' : ( ('N', [ 8.330, 2.791, 12.593 ]), ('H', [ 8.046, 3.726, 12.336 ]), @@ -616,7 +616,7 @@ def pmx_data_file( filename ): ('C', [ 10.094, 4.200, 13.474 ]), ('O', [ 9.519, 5.126, 12.895 ]) ), - 'CYN' : + 'CYN' : ( ('N', [ 8.330, 2.791, 12.593 ]), ('H', [ 8.046, 3.726, 12.336 ]), @@ -630,7 +630,7 @@ def pmx_data_file( filename ): ('C', [ 10.094, 4.200, 13.474 ]), ('O', [ 9.519, 5.126, 12.895 ]) ), - 'GLU' : + 'GLU' : ( ('N', [ 11.129, 4.390, 14.297 ]), ('H', [ 11.607, 3.575, 14.666 ]), @@ -648,7 +648,7 @@ def pmx_data_file( filename ): ('C', [ 13.184, 5.345, 15.197 ]), ('O', [ 13.544, 4.179, 15.372 ]) ), - 'GLH' : + 'GLH' : ( ('N', [ 11.129, 4.390, 14.297 ]), ('H', [ 11.607, 3.575, 14.666 ]), @@ -667,7 +667,7 @@ def pmx_data_file( filename ): ('C', [ 13.184, 5.345, 15.197 ]), ('O', [ 13.544, 4.179, 15.372 ]) ), - 'GLN' : + 'GLN' : ( ('N', [ 13.984, 6.387, 15.452 ]), ('H', [ 13.607, 7.322, 15.344 ]), @@ -687,7 +687,7 @@ def pmx_data_file( filename ): ('C', [ 15.697, 7.807, 16.404 ]), ('O', [ 15.147, 8.743, 15.823 ]) ), - 'GLY' : + 'GLY' : ( ('N', [ 16.653, 8.006, 17.314 ]), ('H', [ 17.133, 7.204, 17.704 ]), @@ -697,7 +697,7 @@ def pmx_data_file( filename ): ('C', [ 18.739, 8.968, 18.109 ]), ('O', [ 19.039, 7.810, 18.406 ]) ), - 'HIS' : + 'HIS' : ( ('N', [ 19.586, 9.994, 18.257 ]), ('H', [ 19.289, 10.931, 18.012 ]), @@ -717,7 +717,7 @@ def pmx_data_file( filename ): ('C', [ 21.459, 11.379, 18.941 ]), ('O', [ 21.037, 12.255, 18.185 ]) ), - 'HIE' : + 'HIE' : ( ('N', [ 19.586, 9.994, 18.257 ]), ('H', [ 19.289, 10.931, 18.012 ]), @@ -737,7 +737,7 @@ def pmx_data_file( filename ): ('C', [ 21.459, 11.379, 18.941 ]), ('O', [ 21.037, 12.255, 18.185 ]) ), - 'HID' : + 'HID' : ( ('N', [ 19.586, 9.994, 18.257 ]), ('H', [ 19.289, 10.931, 18.012 ]), @@ -757,7 +757,7 @@ def pmx_data_file( filename ): ('C', [ 21.459, 11.379, 18.941 ]), ('O', [ 21.037, 12.255, 18.185 ]) ), - 'HIP' : + 'HIP' : ( ('N', [ 19.586, 9.994, 18.257 ]), ('H', [ 19.289, 10.931, 18.012 ]), @@ -778,7 +778,7 @@ def pmx_data_file( filename ): ('C', [ 21.459, 11.379, 18.941 ]), ('O', [ 21.037, 12.255, 18.185 ]) ), - 'ILE' : + 'ILE' : ( ('N', [ 22.324, 11.629, 19.931 ]), ('H', [ 22.723, 10.840, 20.429 ]), @@ -800,7 +800,7 @@ def pmx_data_file( filename ): ('C', [ 24.267, 12.571, 20.995 ]), ('O', [ 24.368, 11.498, 21.586 ]) ), - 'LEU' : + 'LEU' : ( ('N', [ 25.254, 13.482, 20.971 ]), ('H', [ 25.045, 14.387, 20.571 ]), @@ -822,7 +822,7 @@ def pmx_data_file( filename ): ('C', [ 26.945, 14.893, 22.048 ]), ('O', [ 26.307, 15.843, 21.593 ]) ), - 'LYS' : + 'LYS' : ( ('N', [ 28.024, 15.069, 22.828 ]), ('H', [ 28.522, 14.250, 23.158 ]), @@ -847,7 +847,7 @@ def pmx_data_file( filename ): ('C', [ 30.019, 16.018, 23.866 ]), ('O', [ 30.171, 14.936, 24.428 ]) ), - 'LYP' : + 'LYP' : ( ('N', [ 28.024, 15.069, 22.828 ]), ('H', [ 28.522, 14.250, 23.158 ]), @@ -872,7 +872,7 @@ def pmx_data_file( filename ): ('C', [ 30.019, 16.018, 23.866 ]), ('O', [ 30.171, 14.936, 24.428 ]) ), - 'LYN' : + 'LYN' : ( ('N', [ 28.024, 15.069, 22.828 ]), ('H', [ 28.522, 14.250, 23.158 ]), @@ -896,7 +896,7 @@ def pmx_data_file( filename ): ('C', [ 30.019, 16.018, 23.866 ]), ('O', [ 30.171, 14.936, 24.428 ]) ), - 'MET' : + 'MET' : ( ('N', [ 30.974, 16.962, 23.847 ]), ('H', [ 30.754, 17.857, 23.430 ]), @@ -916,7 +916,7 @@ def pmx_data_file( filename ): ('C', [ 32.632, 18.436, 24.873 ]), ('O', [ 31.926, 19.328, 24.407 ]) ), - 'PHE' : + 'PHE' : ( ('N', [ 33.691, 18.694, 25.659 ]), ('H', [ 34.285, 17.921, 25.946 ]), @@ -939,7 +939,7 @@ def pmx_data_file( filename ): ('C', [ 35.732, 19.747, 26.542 ]), ('O', [ 36.101, 18.575, 26.655 ]) ), - 'PRO' : + 'PRO' : ( ('N', [ 36.562, 20.776, 26.860 ]), ('CA', [ 37.872, 20.686, 27.534 ]), @@ -956,7 +956,7 @@ def pmx_data_file( filename ): ('C', [ 37.694, 20.372, 29.037 ]), ('O', [ 36.575, 20.369, 29.556 ]) ), - 'SER' : + 'SER' : ( ('N', [ 38.802, 20.160, 29.750 ]), ('H', [ 39.715, 20.217, 29.317 ]), @@ -970,7 +970,7 @@ def pmx_data_file( filename ): ('C', [ 40.346, 20.078, 31.621 ]), ('O', [ 41.224, 20.117, 30.758 ]) ), - 'THR' : + 'THR' : ( ('N', [ 40.597, 20.176, 32.935 ]), ('H', [ 39.835, 20.071, 33.591 ]), @@ -987,7 +987,7 @@ def pmx_data_file( filename ): ('C', [ 41.662, 19.864, 35.077 ]), ('O', [ 40.564, 20.090, 35.587 ]) ), - 'TRP' : + 'TRP' : ( ('N', [ 42.684, 19.332, 35.765 ]), ('H', [ 43.592, 19.274, 35.320 ]), @@ -1014,7 +1014,7 @@ def pmx_data_file( filename ): ('C', [ 44.158, 19.093, 37.693 ]), ('O', [ 45.085, 19.012, 36.890 ]) ), - 'TYR' : + 'TYR' : ( ('N', [ 44.347, 19.255, 39.010 ]), ('H', [ 43.549, 19.215, 39.631 ]), @@ -1038,7 +1038,7 @@ def pmx_data_file( filename ): ('C', [ 45.385, 18.925, 41.173 ]), ('O', [ 44.263, 19.064, 41.661 ]) ), - 'VAL' : + 'VAL' : ( ('N', [ 46.436, 18.490, 41.874 ]), ('H', [ 47.353, 18.513, 41.443 ]), @@ -1061,627 +1061,627 @@ def pmx_data_file( filename ): _bonds = { - 'ALA' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', '1HB'), - ('CB', '2HB'), - ('CB', '3HB'), - ), - 'CYS' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', '1HB'), - ('CB', '2HB'), - ('CB', 'SG'), - ('SG', 'HG'), - ), - 'GLU' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', '1HB'), - ('CB', '2HB'), - ('CB', 'CG'), - ('CG', '1HG'), - ('CG', '2HG'), - ('CG', 'CD'), - ('CD', 'OE1'), - ('CD', 'OE2'), - ('OE2', 'HE2'), - ), - 'ASP' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', '1HB'), - ('CB', '2HB'), - ('CB', 'CG'), - ('CG', 'OD1'), - ('CG', 'OD2'), - ('OD2', 'HD2'), - ), - 'GLY' : ( - ('CA', 'C'), - ('CA', '1HA'), - ('CA', '2HA'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ), - 'PHE' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', '1HB'), - ('CB', '2HB'), - ('CB', 'CG'), - ('CG', 'CD1'), - ('CG', 'CD2'), - ('CD1', 'HD1'), - ('CD1', 'CE1'), - ('CD2', 'HD2'), - ('CD2', 'CE2'), - ('CE1', 'HE1'), - ('CE2', 'HE2'), - ('CE1', 'CZ'), - ('CE2', 'CZ'), - ('CZ', 'HZ'), - ), - 'ILE' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', 'HB'), - ('CB', 'CG1'), - ('CB', 'CG2'), - ('CG1', '1HG1'), - ('CG1', '2HG1'), - ('CG1', 'CD1'), - ('CG2', '1HG2'), - ('CG2', '2HG2'), - ('CG2', '3HG2'), - ('CD1', '1HD1'), - ('CD1', '2HD1'), - ('CD1', '3HD1'), - ), - 'HIS' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', '1HB'), - ('CB', '2HB'), - ('CB', 'CG'), - ('CG', 'ND1'), - ('CG', 'CD2'), - ('ND1', 'CE1'), - ('ND1', 'HD1'), - ('CD2', 'HD2'), - ('CD2', 'NE2'), - ('CE1', 'HE1'), - ('CE1', 'NE2'), - ('NE2', 'HE2'), - ), - 'LYS' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', '1HB'), - ('CB', '2HB'), - ('CB', 'CG'), - ('CG', '1HG'), - ('CG', '2HG'), - ('CG', 'CD'), - ('CD', '1HD'), - ('CD', '2HD'), - ('CD', 'CE'), - ('CE', '1HE'), - ('CE', '2HE'), - ('CE', 'NZ'), - ('NZ', '1HZ'), - ('NZ', '2HZ'), - ('NZ', '3HZ'), - ), - 'MET' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', '1HB'), - ('CB', '2HB'), - ('CB', 'CG'), - ('CG', '1HG'), - ('CG', '2HG'), - ('CG', 'SD'), - ('SD', 'CE'), - ('CE', '1HE'), - ('CE', '2HE'), - ('CE', '3HE'), - ), - 'LEU' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', '1HB'), - ('CB', '2HB'), - ('CB', 'CG'), - ('CG', 'HG'), - ('CG', 'CD1'), - ('CG', 'CD2'), - ('CD1', '1HD1'), - ('CD1', '2HD1'), - ('CD1', '3HD1'), - ('CD2', '1HD2'), - ('CD2', '2HD2'), - ('CD2', '3HD2'), - ), - 'ASN' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', '1HB'), - ('CB', '2HB'), - ('CB', 'CG'), - ('CG', 'OD1'), - ('CG', 'ND2'), - ('ND2', '1HD2'), - ('ND2', '2HD2'), - ), - 'GLN' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', '1HB'), - ('CB', '2HB'), - ('CB', 'CG'), - ('CG', '1HG'), - ('CG', '2HG'), - ('CG', 'CD'), - ('CD', 'OE1'), - ('CD', 'NE2'), - ('NE2', '1HE2'), - ('NE2', '2HE2'), - ), - 'PRO' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'CD'), - ('N', '1H'), - ('N', '2H'), - ('CB', '1HB'), - ('CB', '2HB'), - ('CB', 'CG'), - ('CG', '1HG'), - ('CG', '2HG'), - ('CG', 'CD'), - ('CD', '1HD'), - ('CD', '2HD'), - ), - 'SER' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', '1HB'), - ('CB', '2HB'), - ('CB', 'OG'), - ('OG', 'HG'), - ), - 'ARG' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', '1HB'), - ('CB', '2HB'), - ('CB', 'CG'), - ('CG', '1HG'), - ('CG', '2HG'), - ('CG', 'CD'), - ('CD', '1HD'), - ('CD', '2HD'), - ('CD', 'NE'), - ('NE', 'HE'), - ('NE', 'CZ'), - ('CZ', 'NH1'), - ('CZ', 'NH2'), - ('NH1', '1HH1'), - ('NH1', '2HH1'), - ('NH2', '1HH2'), - ('NH2', '2HH2'), - ), - 'THR' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', 'HB'), - ('CB', 'OG1'), - ('CB', 'CG2'), - ('OG1', 'HG1'), - ('CG2', '1HG2'), - ('CG2', '2HG2'), - ('CG2', '3HG2'), - ), - 'TRP' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', '1HB'), - ('CB', '2HB'), - ('CB', 'CG'), - ('CG', 'CD1'), - ('CG', 'CD2'), - ('CD1', 'HD1'), - ('CD1', 'NE1'), - ('CD2', 'CE2'), + 'ALA' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', '1HB'), + ('CB', '2HB'), + ('CB', '3HB'), + ), + 'CYS' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', '1HB'), + ('CB', '2HB'), + ('CB', 'SG'), + ('SG', 'HG'), + ), + 'GLU' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', '1HB'), + ('CB', '2HB'), + ('CB', 'CG'), + ('CG', '1HG'), + ('CG', '2HG'), + ('CG', 'CD'), + ('CD', 'OE1'), + ('CD', 'OE2'), + ('OE2', 'HE2'), + ), + 'ASP' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', '1HB'), + ('CB', '2HB'), + ('CB', 'CG'), + ('CG', 'OD1'), + ('CG', 'OD2'), + ('OD2', 'HD2'), + ), + 'GLY' : ( + ('CA', 'C'), + ('CA', '1HA'), + ('CA', '2HA'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ), + 'PHE' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', '1HB'), + ('CB', '2HB'), + ('CB', 'CG'), + ('CG', 'CD1'), + ('CG', 'CD2'), + ('CD1', 'HD1'), + ('CD1', 'CE1'), + ('CD2', 'HD2'), + ('CD2', 'CE2'), + ('CE1', 'HE1'), + ('CE2', 'HE2'), + ('CE1', 'CZ'), + ('CE2', 'CZ'), + ('CZ', 'HZ'), + ), + 'ILE' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', 'HB'), + ('CB', 'CG1'), + ('CB', 'CG2'), + ('CG1', '1HG1'), + ('CG1', '2HG1'), + ('CG1', 'CD1'), + ('CG2', '1HG2'), + ('CG2', '2HG2'), + ('CG2', '3HG2'), + ('CD1', '1HD1'), + ('CD1', '2HD1'), + ('CD1', '3HD1'), + ), + 'HIS' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', '1HB'), + ('CB', '2HB'), + ('CB', 'CG'), + ('CG', 'ND1'), + ('CG', 'CD2'), + ('ND1', 'CE1'), + ('ND1', 'HD1'), + ('CD2', 'HD2'), + ('CD2', 'NE2'), + ('CE1', 'HE1'), + ('CE1', 'NE2'), + ('NE2', 'HE2'), + ), + 'LYS' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', '1HB'), + ('CB', '2HB'), + ('CB', 'CG'), + ('CG', '1HG'), + ('CG', '2HG'), + ('CG', 'CD'), + ('CD', '1HD'), + ('CD', '2HD'), + ('CD', 'CE'), + ('CE', '1HE'), + ('CE', '2HE'), + ('CE', 'NZ'), + ('NZ', '1HZ'), + ('NZ', '2HZ'), + ('NZ', '3HZ'), + ), + 'MET' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', '1HB'), + ('CB', '2HB'), + ('CB', 'CG'), + ('CG', '1HG'), + ('CG', '2HG'), + ('CG', 'SD'), + ('SD', 'CE'), + ('CE', '1HE'), + ('CE', '2HE'), + ('CE', '3HE'), + ), + 'LEU' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', '1HB'), + ('CB', '2HB'), + ('CB', 'CG'), + ('CG', 'HG'), + ('CG', 'CD1'), + ('CG', 'CD2'), + ('CD1', '1HD1'), + ('CD1', '2HD1'), + ('CD1', '3HD1'), + ('CD2', '1HD2'), + ('CD2', '2HD2'), + ('CD2', '3HD2'), + ), + 'ASN' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', '1HB'), + ('CB', '2HB'), + ('CB', 'CG'), + ('CG', 'OD1'), + ('CG', 'ND2'), + ('ND2', '1HD2'), + ('ND2', '2HD2'), + ), + 'GLN' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', '1HB'), + ('CB', '2HB'), + ('CB', 'CG'), + ('CG', '1HG'), + ('CG', '2HG'), + ('CG', 'CD'), + ('CD', 'OE1'), + ('CD', 'NE2'), + ('NE2', '1HE2'), + ('NE2', '2HE2'), + ), + 'PRO' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'CD'), + ('N', '1H'), + ('N', '2H'), + ('CB', '1HB'), + ('CB', '2HB'), + ('CB', 'CG'), + ('CG', '1HG'), + ('CG', '2HG'), + ('CG', 'CD'), + ('CD', '1HD'), + ('CD', '2HD'), + ), + 'SER' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', '1HB'), + ('CB', '2HB'), + ('CB', 'OG'), + ('OG', 'HG'), + ), + 'ARG' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', '1HB'), + ('CB', '2HB'), + ('CB', 'CG'), + ('CG', '1HG'), + ('CG', '2HG'), + ('CG', 'CD'), + ('CD', '1HD'), + ('CD', '2HD'), + ('CD', 'NE'), + ('NE', 'HE'), + ('NE', 'CZ'), + ('CZ', 'NH1'), + ('CZ', 'NH2'), + ('NH1', '1HH1'), + ('NH1', '2HH1'), + ('NH2', '1HH2'), + ('NH2', '2HH2'), + ), + 'THR' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', 'HB'), + ('CB', 'OG1'), + ('CB', 'CG2'), + ('OG1', 'HG1'), + ('CG2', '1HG2'), + ('CG2', '2HG2'), + ('CG2', '3HG2'), + ), + 'TRP' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', '1HB'), + ('CB', '2HB'), + ('CB', 'CG'), + ('CG', 'CD1'), + ('CG', 'CD2'), + ('CD1', 'HD1'), + ('CD1', 'NE1'), + ('CD2', 'CE2'), ('CD2', 'CE3'), - ('NE1', 'HE1'), - ('CE2', 'CZ2'), + ('NE1', 'HE1'), + ('CE2', 'CZ2'), ('CE2', 'NE1'), - ('CE3', 'HE3'), - ('CE3', 'CZ3'), - ('CZ2', 'HZ2'), - ('CZ2', 'CH2'), - ('CZ3', 'HZ3'), - ('CZ3', 'CH2'), - ('CH2', 'HH2'), - ), - 'VAL' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', 'HB'), - ('CB', 'CG1'), - ('CB', 'CG2'), - ('CG1', '1HG1'), - ('CG1', '2HG1'), - ('CG1', '3HG1'), - ('CG2', '1HG2'), - ('CG2', '2HG2'), - ('CG2', '3HG2'), - ), - 'TYR' : ( - ('CA', 'C'), - ('CA', 'HA'), - ('CA', 'CB'), - ('N', 'CA'), - ('C', 'O'), - ('C', 'O1'), - ('C', 'O2'), - ('C', 'OXT'), - ('N', 'H'), - ('N', '1H'), - ('N', '2H'), - ('N', '3H'), - ('CB', '1HB'), - ('CB', '2HB'), - ('CB', 'CG'), - ('CG', 'CD1'), - ('CG', 'CD2'), - ('CD1', 'HD1'), - ('CD1', 'CE1'), - ('CD2', 'HD2'), - ('CD2', 'CE2'), - ('CE1', 'HE1'), - ('CE2', 'HE2'), - ('CE1', 'CZ'), - ('CE2', 'CZ'), - ('CZ', 'OH'), - ('OH', 'HH'), - ), + ('CE3', 'HE3'), + ('CE3', 'CZ3'), + ('CZ2', 'HZ2'), + ('CZ2', 'CH2'), + ('CZ3', 'HZ3'), + ('CZ3', 'CH2'), + ('CH2', 'HH2'), + ), + 'VAL' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', 'HB'), + ('CB', 'CG1'), + ('CB', 'CG2'), + ('CG1', '1HG1'), + ('CG1', '2HG1'), + ('CG1', '3HG1'), + ('CG2', '1HG2'), + ('CG2', '2HG2'), + ('CG2', '3HG2'), + ), + 'TYR' : ( + ('CA', 'C'), + ('CA', 'HA'), + ('CA', 'CB'), + ('N', 'CA'), + ('C', 'O'), + ('C', 'O1'), + ('C', 'O2'), + ('C', 'OXT'), + ('N', 'H'), + ('N', '1H'), + ('N', '2H'), + ('N', '3H'), + ('CB', '1HB'), + ('CB', '2HB'), + ('CB', 'CG'), + ('CG', 'CD1'), + ('CG', 'CD2'), + ('CD1', 'HD1'), + ('CD1', 'CE1'), + ('CD2', 'HD2'), + ('CD2', 'CE2'), + ('CE1', 'HE1'), + ('CE2', 'HE2'), + ('CE1', 'CZ'), + ('CE2', 'CZ'), + ('CZ', 'OH'), + ('OH', 'HH'), + ), } _aliases = { - 'ALA': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HB3':'3HB', - }, - 'NALA': { + 'ALA': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HB3':'3HB', + }, + 'NALA': { 'H1':'1H', 'H2':'2H', 'H3':'3H', 'HB1':'1HB', 'HB2':'2HB', 'HB3':'3HB', - }, - 'CALA': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HB3':'3HB', - }, - 'ARG': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - 'HD1':'1HD', - 'HD2':'2HD', - 'HH11':'1HH1', - 'HH12':'2HH1', - 'HH21':'1HH2', - 'HH22':'2HH2', - }, - 'NARG': { + }, + 'CALA': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HB3':'3HB', + }, + 'ARG': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + 'HD1':'1HD', + 'HD2':'2HD', + 'HH11':'1HH1', + 'HH12':'2HH1', + 'HH21':'1HH2', + 'HH22':'2HH2', + }, + 'NARG': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - 'HD1':'1HD', - 'HD2':'2HD', - 'HH11':'1HH1', - 'HH12':'2HH1', - 'HH21':'1HH2', - 'HH22':'2HH2', - }, - 'CARG': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - 'HD1':'1HD', - 'HD2':'2HD', - 'HH11':'1HH1', - 'HH12':'2HH1', - 'HH21':'1HH2', - 'HH22':'2HH2', - }, - 'ASP': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'ASPP': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'NASP': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + 'HD1':'1HD', + 'HD2':'2HD', + 'HH11':'1HH1', + 'HH12':'2HH1', + 'HH21':'1HH2', + 'HH22':'2HH2', + }, + 'CARG': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + 'HD1':'1HD', + 'HD2':'2HD', + 'HH11':'1HH1', + 'HH12':'2HH1', + 'HH21':'1HH2', + 'HH22':'2HH2', + }, + 'ASP': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'ASPP': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'NASP': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'CASP': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'ASH': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'NASH': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'CASP': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'ASH': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'NASH': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'CASH': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'ASN': { - 'HB1':'1HB', - 'HB2':'2HB', + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'CASH': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'ASN': { + 'HB1':'1HB', + 'HB2':'2HB', 'HD21':'1HD2', 'HD22':'2HD2', - }, - 'NASN': { + }, + 'NASN': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', + 'HB1':'1HB', + 'HB2':'2HB', 'HD21':'1HD2', 'HD22':'2HD2', - }, - 'CASN': { - 'HB1':'1HB', - 'HB2':'2HB', + }, + 'CASN': { + 'HB1':'1HB', + 'HB2':'2HB', 'HD21':'1HD2', 'HD22':'2HD2', - }, - 'CYS': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - #MS: HG1 i only in charmm... - }, - 'CYN': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'CYM': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'CYS2': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'CCYX': { - 'HB1':'1HB', - 'HB2':'2HB', - }, + }, + 'CYS': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + #MS: HG1 i only in charmm... + }, + 'CYN': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'CYM': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'CYS2': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'CCYX': { + 'HB1':'1HB', + 'HB2':'2HB', + }, 'CYSH': { 'HB1':'1HB', 'HB2':'2HB', }, - 'GLU': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - }, + 'GLU': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + }, 'GLUH': { 'HB1':'1HB', 'HB2':'2HB', @@ -1689,94 +1689,94 @@ def pmx_data_file( filename ): 'HG2':'2HG', 'HE2':'2HE', }, - 'GLUP': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - }, - 'NGLU': { + 'GLUP': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + }, + 'NGLU': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - }, - 'CGLU': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - }, - 'GLH': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - }, - 'NGLH': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + }, + 'CGLU': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + }, + 'GLH': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + }, + 'NGLH': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - }, - 'CGLH': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - }, - 'GLN': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + }, + 'CGLH': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + }, + 'GLN': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', 'HE21':'1HE2', 'HE22':'2HE2', - }, - 'NGLN': { + }, + 'NGLN': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', 'HE21':'1HE2', 'HE22':'2HE2', - }, - 'CGLN': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', + }, + 'CGLN': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', 'HE21':'1HE2', 'HE22':'2HE2', - }, - 'GLY': { - 'HA1':'1HA', - 'HA2':'2HA', - }, - 'NGLY': { + }, + 'GLY': { + 'HA1':'1HA', + 'HA2':'2HA', + }, + 'NGLY': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HA1':'1HA', - 'HA2':'2HA', - }, - 'CGLY': { - 'HA1':'1HA', - 'HA2':'2HA', - }, - 'HIS': { - 'HB1':'1HB', - 'HB2':'2HB', - }, + 'HA1':'1HA', + 'HA2':'2HA', + }, + 'CGLY': { + 'HA1':'1HA', + 'HA2':'2HA', + }, + 'HIS': { + 'HB1':'1HB', + 'HB2':'2HB', + }, 'HIS1': { 'HB1':'1HB', 'HB2':'2HB', @@ -1785,10 +1785,10 @@ def pmx_data_file( filename ): 'HB1':'1HB', 'HB2':'2HB', }, - 'HSE': { - 'HB1':'1HB', - 'HB2':'2HB', - }, + 'HSE': { + 'HB1':'1HB', + 'HB2':'2HB', + }, 'HISE': { 'HB1':'1HB', 'HB2':'2HB', @@ -1797,64 +1797,64 @@ def pmx_data_file( filename ): 'HB1':'1HB', 'HB2':'2HB', }, - 'HID': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'HSD': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'NHID': { + 'HID': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'HSD': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'NHID': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'CHID': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'HIE': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'NHIE': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'CHID': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'HIE': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'NHIE': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'CHIE': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'NHIP': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'CHIE': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'NHIP': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'CHIP': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'HIP': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'HSP': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'ILE': { - 'CD':'CD1', - 'HD1':'1HD1', - 'HD2':'2HD1', - 'HD3':'3HD1', + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'CHIP': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'HIP': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'HSP': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'ILE': { + 'CD':'CD1', + 'HD1':'1HD1', + 'HD2':'2HD1', + 'HD3':'3HD1', 'HG11':'1HG1', 'HG12':'2HG1', 'HG21':'1HG2', @@ -1863,15 +1863,15 @@ def pmx_data_file( filename ): 'HD11':'1HD1', 'HD12':'2HD1', 'HD13':'3HD1', - }, - 'NILE': { + }, + 'NILE': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'CD':'CD1', - 'HD1':'1HD1', - 'HD2':'2HD1', - 'HD3':'3HD1', + 'CD':'CD1', + 'HD1':'1HD1', + 'HD2':'2HD1', + 'HD3':'3HD1', 'HG11':'1HG1', 'HG12':'2HG1', 'HG21':'1HG2', @@ -1880,9 +1880,9 @@ def pmx_data_file( filename ): 'HD11':'1HD1', 'HD12':'2HD1', 'HD13':'3HD1', - }, - 'CILE': { - 'CD':'CD1', + }, + 'CILE': { + 'CD':'CD1', 'HG11':'1HG1', 'HG12':'2HG1', 'HG21':'1HG2', @@ -1891,56 +1891,56 @@ def pmx_data_file( filename ): 'HD11':'1HD1', 'HD12':'2HD1', 'HD13':'3HD1', - 'HD1':'1HD1', - 'HD2':'2HD1', - 'HD3':'3HD1', - }, - 'LEU': { - 'HB1':'1HB', - 'HB2':'2HB', + 'HD1':'1HD1', + 'HD2':'2HD1', + 'HD3':'3HD1', + }, + 'LEU': { + 'HB1':'1HB', + 'HB2':'2HB', 'HD11':'1HD1', 'HD12':'2HD1', 'HD13':'3HD1', 'HD21':'1HD2', 'HD22':'2HD2', 'HD23':'3HD2', - }, - 'NLEU': { + }, + 'NLEU': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', + 'HB1':'1HB', + 'HB2':'2HB', 'HD11':'1HD1', 'HD12':'2HD1', 'HD13':'3HD1', 'HD21':'1HD2', 'HD22':'2HD2', 'HD23':'3HD2', - }, - 'CLEU': { - 'HB1':'1HB', - 'HB2':'2HB', + }, + 'CLEU': { + 'HB1':'1HB', + 'HB2':'2HB', 'HD11':'1HD1', 'HD12':'2HD1', 'HD13':'3HD1', 'HD21':'1HD2', 'HD22':'2HD2', 'HD23':'3HD2', - }, - 'LYS': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - 'HD1':'1HD', - 'HD2':'2HD', - 'HE1':'1HE', - 'HE2':'2HE', - 'HZ1':'1HZ', - 'HZ2':'2HZ', - 'HZ3':'3HZ', - }, + }, + 'LYS': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + 'HD1':'1HD', + 'HD2':'2HD', + 'HE1':'1HE', + 'HE2':'2HE', + 'HZ1':'1HZ', + 'HZ2':'2HZ', + 'HZ3':'3HZ', + }, 'LYSH': { 'HB1':'1HB', 'HB2':'2HB', @@ -1978,232 +1978,232 @@ def pmx_data_file( filename ): 'HZ1':'1HZ', 'HZ2':'2HZ', }, - 'NLYS': { + 'NLYS': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - 'HD1':'1HD', - 'HD2':'2HD', - 'HE1':'1HE', - 'HE2':'2HE', - 'HZ1':'1HZ', - 'HZ2':'2HZ', - 'HZ3':'3HZ', - }, - 'CLYS': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - 'HD1':'1HD', - 'HD2':'2HD', - 'HE1':'1HE', - 'HE2':'2HE', - 'HZ1':'1HZ', - 'HZ2':'2HZ', - 'HZ3':'3HZ', - }, - 'LYP': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - 'HD1':'1HD', - 'HD2':'2HD', - 'HE1':'1HE', - 'HE2':'2HE', - 'HZ1':'1HZ', - 'HZ2':'2HZ', - 'HZ3':'3HZ', - }, - 'NLYP': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + 'HD1':'1HD', + 'HD2':'2HD', + 'HE1':'1HE', + 'HE2':'2HE', + 'HZ1':'1HZ', + 'HZ2':'2HZ', + 'HZ3':'3HZ', + }, + 'CLYS': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + 'HD1':'1HD', + 'HD2':'2HD', + 'HE1':'1HE', + 'HE2':'2HE', + 'HZ1':'1HZ', + 'HZ2':'2HZ', + 'HZ3':'3HZ', + }, + 'LYP': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + 'HD1':'1HD', + 'HD2':'2HD', + 'HE1':'1HE', + 'HE2':'2HE', + 'HZ1':'1HZ', + 'HZ2':'2HZ', + 'HZ3':'3HZ', + }, + 'NLYP': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - 'HD1':'1HD', - 'HD2':'2HD', - 'HE1':'1HE', - 'HE2':'2HE', - 'HZ1':'1HZ', - 'HZ2':'2HZ', - 'HZ3':'3HZ', - }, - 'CLYP': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - 'HD1':'1HD', - 'HD2':'2HD', - 'HE1':'1HE', - 'HE2':'2HE', - 'HZ1':'1HZ', - 'HZ2':'2HZ', - 'HZ3':'3HZ', - }, - 'MET': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - 'HE1':'1HE', - 'HE2':'2HE', - 'HE3':'3HE', - }, - 'NMET': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + 'HD1':'1HD', + 'HD2':'2HD', + 'HE1':'1HE', + 'HE2':'2HE', + 'HZ1':'1HZ', + 'HZ2':'2HZ', + 'HZ3':'3HZ', + }, + 'CLYP': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + 'HD1':'1HD', + 'HD2':'2HD', + 'HE1':'1HE', + 'HE2':'2HE', + 'HZ1':'1HZ', + 'HZ2':'2HZ', + 'HZ3':'3HZ', + }, + 'MET': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + 'HE1':'1HE', + 'HE2':'2HE', + 'HE3':'3HE', + }, + 'NMET': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - 'HE1':'1HE', - 'HE2':'2HE', - 'HE3':'3HE', - }, - 'CMET': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - 'HE1':'1HE', - 'HE2':'2HE', - 'HE3':'3HE', - }, - 'PHE': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'NPHE': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + 'HE1':'1HE', + 'HE2':'2HE', + 'HE3':'3HE', + }, + 'CMET': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + 'HE1':'1HE', + 'HE2':'2HE', + 'HE3':'3HE', + }, + 'PHE': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'NPHE': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'CPHE': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'PRO': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - 'HD1':'1HD', - 'HD2':'2HD', - }, - 'NPRO': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'CPHE': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'PRO': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + 'HD1':'1HD', + 'HD2':'2HD', + }, + 'NPRO': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - 'HD1':'1HD', - 'HD2':'2HD', - }, - 'CPRO': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - 'HG2':'2HG', - 'HD1':'1HD', - 'HD2':'2HD', - }, - 'SER': { - 'HB1':'1HB', - 'HB2':'2HB', - 'HG1':'1HG', - }, + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + 'HD1':'1HD', + 'HD2':'2HD', + }, + 'CPRO': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + 'HG2':'2HG', + 'HD1':'1HD', + 'HD2':'2HD', + }, + 'SER': { + 'HB1':'1HB', + 'HB2':'2HB', + 'HG1':'1HG', + }, # phosphoserine in charmm36 - 'SP1': { - 'HB1':'1HB', - 'HB2':'2HB', - }, + 'SP1': { + 'HB1':'1HB', + 'HB2':'2HB', + }, # phosphoserine in charmm36 - 'SP2': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'NSER': { + 'SP2': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'NSER': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'CSER': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'THR': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'CSER': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'THR': { 'HG21':'1HG2', 'HG22':'2HG2', 'HG23':'3HG2', - }, - 'NTHR': { + }, + 'NTHR': { 'H1':'1H', 'H2':'2H', 'H3':'3H', 'HG21':'1HG2', 'HG22':'2HG2', 'HG23':'3HG2', - }, - 'CTHR': { + }, + 'CTHR': { 'HG21':'1HG2', 'HG22':'2HG2', 'HG23':'3HG2', - }, - 'TRP': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'CTRP': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'NTRP': { + }, + 'TRP': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'CTRP': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'NTRP': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'TYR': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'NTYR': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'TYR': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'NTYR': { 'H1':'1H', 'H2':'2H', 'H3':'3H', - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'CTYR': { - 'HB1':'1HB', - 'HB2':'2HB', - }, - 'VAL': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'CTYR': { + 'HB1':'1HB', + 'HB2':'2HB', + }, + 'VAL': { 'HG11':'1HG1', 'HG12':'2HG1', 'HG13':'3HG1', 'HG21':'1HG2', 'HG22':'2HG2', 'HG23':'3HG2', - }, - 'NVAL': { + }, + 'NVAL': { 'H1':'1H', 'H2':'2H', 'H3':'3H', @@ -2213,1909 +2213,1909 @@ def pmx_data_file( filename ): 'HG21':'1HG2', 'HG22':'2HG2', 'HG23':'3HG2', - }, - 'CVAL': { + }, + 'CVAL': { 'HG11':'1HG1', 'HG12':'2HG1', 'HG13':'3HG1', 'HG21':'1HG2', 'HG22':'2HG2', 'HG23':'3HG2', - }, - 'DA': { + }, + 'DA': { '1H5\'':'H5\'1', '2H5\'':'H5\'2', '1H2\'':'H2\'1', '2H2\'':'H2\'2', - }, - 'DA5': { + }, + 'DA5': { '1H5\'':'H5\'1', '2H5\'':'H5\'2', '1H2\'':'H2\'1', '2H2\'':'H2\'2', - }, - 'DA3': { + }, + 'DA3': { '1H5\'':'H5\'1', '2H5\'':'H5\'2', '1H2\'':'H2\'1', '2H2\'':'H2\'2', - }, - 'DAN': { + }, + 'DAN': { '1H5\'':'H5\'1', '2H5\'':'H5\'2', '1H2\'':'H2\'1', '2H2\'':'H2\'2', - }, - 'DT': { + }, + 'DT': { '1H5\'':'H5\'1', '2H5\'':'H5\'2', '1H2\'':'H2\'1', '2H2\'':'H2\'2', - }, - 'DT5': { + }, + 'DT5': { '1H5\'':'H5\'1', '2H5\'':'H5\'2', '1H2\'':'H2\'1', '2H2\'':'H2\'2', - }, - 'DT3': { + }, + 'DT3': { '1H5\'':'H5\'1', '2H5\'':'H5\'2', '1H2\'':'H2\'1', '2H2\'':'H2\'2', - }, - 'DTN': { + }, + 'DTN': { '1H5\'':'H5\'1', '2H5\'':'H5\'2', '1H2\'':'H2\'1', '2H2\'':'H2\'2', - }, - 'DG': { + }, + 'DG': { '1H5\'':'H5\'1', '2H5\'':'H5\'2', '1H2\'':'H2\'1', '2H2\'':'H2\'2', - }, - 'DG5': { + }, + 'DG5': { '1H5\'':'H5\'1', '2H5\'':'H5\'2', '1H2\'':'H2\'1', '2H2\'':'H2\'2', - }, - 'DG3': { + }, + 'DG3': { '1H5\'':'H5\'1', '2H5\'':'H5\'2', '1H2\'':'H2\'1', '2H2\'':'H2\'2', - }, - 'DGN': { + }, + 'DGN': { '1H5\'':'H5\'1', '2H5\'':'H5\'2', '1H2\'':'H2\'1', '2H2\'':'H2\'2', - }, - 'DC': { + }, + 'DC': { '1H5\'':'H5\'1', '2H5\'':'H5\'2', '1H2\'':'H2\'1', '2H2\'':'H2\'2', - }, - 'DC5': { + }, + 'DC5': { '1H5\'':'H5\'1', '2H5\'':'H5\'2', '1H2\'':'H2\'1', '2H2\'':'H2\'2', - }, - 'DC3': { + }, + 'DC3': { '1H5\'':'H5\'1', '2H5\'':'H5\'2', '1H2\'':'H2\'1', '2H2\'':'H2\'2', - }, - 'DCN': { + }, + 'DCN': { '1H5\'':'H5\'1', '2H5\'':'H5\'2', '1H2\'':'H2\'1', '2H2\'':'H2\'2', - }, + }, } _atom_types = { - 'GENERIC': { - "C" : { - 'type':'CGEN', - 'hyb':'' - }, - "CL" : { - 'type':'CL', - 'hyb':'' - }, - "I" : { - 'type':'IGEN', - 'hyb':'' - }, - "NA" : { - 'type':'NA', - 'hyb':'' - }, - "K" : { - 'type':'K', - 'hyb':'' - }, - "F" : { - 'type':'FGEN', - 'hyb':'' - }, - "ZN" : { - 'type':'ZN', - 'hyb':'' - }, - "O" : { - 'type':'OGEN', - 'hyb':'' - }, - "N" : { - 'type':'NGEN', - 'hyb':'' - }, - "P" : { - 'type':'PGEN', - 'hyb':'' - }, - "S" : { - 'type':'SGEN', - 'hyb':'' - }, - "FE" : { - 'type':'FEGEN', - 'hyb':'' - }, - "BR" : { - 'type':'BR', - 'hyb':'' - }, - "H" : { - 'type':'HGEN', - 'hyb':'' - }, - "CA" : { - 'type':'CA', - 'hyb':'' - }, - }, - 'DEFAULT': { - "C" : { - 'type':'C', - 'hyb':'sp2' - }, - "OT" : { - 'type':'OH1', - 'hyb':'' - }, - "HO" : { - 'type':'H', - 'hyb':'' - }, - "CB" : { - 'type':'CH2E', - 'hyb':'sp3' - }, - "OXT" : { - 'type':'OC', - 'hyb':'' - }, - "O1" : { - 'type':'OC', - 'hyb':'' - }, - "O2" : { - 'type':'OC', - 'hyb':'' - }, - "OT1" : { - 'type':'OC', - 'hyb':'' - }, - "OT2" : { - 'type':'OC', - 'hyb':'' - }, - "OC1" : { - 'type':'OC', - 'hyb':'' - }, - "OC2" : { - 'type':'OC', - 'hyb':'' + 'GENERIC': { + "C" : { + 'type':'CGEN', + 'hyb':'' + }, + "CL" : { + 'type':'CL', + 'hyb':'' + }, + "I" : { + 'type':'IGEN', + 'hyb':'' + }, + "NA" : { + 'type':'NA', + 'hyb':'' + }, + "K" : { + 'type':'K', + 'hyb':'' + }, + "F" : { + 'type':'FGEN', + 'hyb':'' + }, + "ZN" : { + 'type':'ZN', + 'hyb':'' + }, + "O" : { + 'type':'OGEN', + 'hyb':'' + }, + "N" : { + 'type':'NGEN', + 'hyb':'' + }, + "P" : { + 'type':'PGEN', + 'hyb':'' + }, + "S" : { + 'type':'SGEN', + 'hyb':'' + }, + "FE" : { + 'type':'FEGEN', + 'hyb':'' + }, + "BR" : { + 'type':'BR', + 'hyb':'' + }, + "H" : { + 'type':'HGEN', + 'hyb':'' + }, + "CA" : { + 'type':'CA', + 'hyb':'' + }, + }, + 'DEFAULT': { + "C" : { + 'type':'C', + 'hyb':'sp2' + }, + "OT" : { + 'type':'OH1', + 'hyb':'' + }, + "HO" : { + 'type':'H', + 'hyb':'' + }, + "CB" : { + 'type':'CH2E', + 'hyb':'sp3' + }, + "OXT" : { + 'type':'OC', + 'hyb':'' + }, + "O1" : { + 'type':'OC', + 'hyb':'' + }, + "O2" : { + 'type':'OC', + 'hyb':'' + }, + "OT1" : { + 'type':'OC', + 'hyb':'' + }, + "OT2" : { + 'type':'OC', + 'hyb':'' + }, + "OC1" : { + 'type':'OC', + 'hyb':'' + }, + "OC2" : { + 'type':'OC', + 'hyb':'' }, - "O\'" : { - 'type':'OC', - 'hyb':'' - }, - "O\'\'" : { - 'type':'OC', - 'hyb':'' - }, - "H" : { - 'type':'H', - 'hyb':'' - }, - "1H" : { - 'type':'HC', - 'hyb':'' - }, - "2H" : { - 'type':'HC', - 'hyb':'' - }, - "3H" : { - 'type':'HC', - 'hyb':'' - }, - "CA" : { - 'type':'CA', - 'hyb':'sp3' - }, - "HA" : { - 'type':'HA', - 'hyb':'' - }, - "O" : { - 'type':'O', - 'hyb':'' - }, - "N" : { - 'type':'NH1', - 'hyb':'sp2' - }, - }, - 'ALA': { - "1HB" : { - 'type':'H0', - 'hyb':'' - }, - "CB" : { - 'type':'CH3E', - 'hyb':'sp3' - }, - "3HB" : { - 'type':'H0', - 'hyb':'' - }, - "2HB" : { - 'type':'H0', - 'hyb':'' - }, - }, - 'ARG': { - "2HH2" : { - 'type':'HC', - 'hyb':'' - }, - "2HD" : { - 'type':'HDR', - 'hyb':'' - }, - "2HH1" : { - 'type':'HC', - 'hyb':'' - }, - "CG" : { - 'type':'CH2E', - 'hyb':'sp3' - }, - "NE" : { - 'type':'NH1', - 'hyb':'sp2' - }, - "CD" : { - 'type':'CDR', - 'hyb':'sp3' - }, - "1HB" : { - 'type':'H0', - 'hyb':'' - }, - "CZ" : { - 'type':'C', - 'hyb':'sp2' - }, - "2HG" : { - 'type':'H0', - 'hyb':'' - }, - "NH1" : { - 'type':'NC2', - 'hyb':'sp2' - }, - "1HG" : { - 'type':'H0', - 'hyb':'' - }, - "1HD" : { - 'type':'HDR', - 'hyb':'' - }, - "NH2" : { - 'type':'NC2', - 'hyb':'sp2' - }, - "2HB" : { - 'type':'H0', - 'hyb':'' - }, - "1HH2" : { - 'type':'HC', - 'hyb':'' - }, - "1HH1" : { - 'type':'HC', - 'hyb':'' - }, - "HE" : { - 'type':'H', - 'hyb':'' - }, - }, - 'ASN': { - "1HB" : { - 'type':'H0', - 'hyb':'' - }, - "ND2" : { - 'type':'NH2', - 'hyb':'sp2' - }, - "1HD2" : { - 'type':'H', - 'hyb':'' - }, - "OD1" : { - 'type':'O', - 'hyb':'sp2' - }, - "2HB" : { - 'type':'H0', - 'hyb':'' - }, - "CG" : { - 'type':'C', - 'hyb':'sp2' - }, - "2HD2" : { - 'type':'H', - 'hyb':'' - }, - }, - 'ASP': { - "1HB" : { - 'type':'H0', - 'hyb':'' - }, - "HD2" : { - 'type':'H', - 'hyb':'' - }, - "OD1" : { - 'type':'OC', - 'hyb':'sp2' - }, - "OD2" : { - 'type':'OC', - 'hyb':'sp2' - }, - "2HB" : { - 'type':'H0', - 'hyb':'' - }, - "CG" : { - 'type':'C', - 'hyb':'sp2' - }, - }, - 'CYS': { - "1HB" : { - 'type':'H0', - 'hyb':'' - }, - "2HB" : { - 'type':'H0', - 'hyb':'' - }, - "SG" : { - 'type':'S', - 'hyb':'sp3' - }, - "HG" : { - 'type':'H0', - 'hyb':'' - }, - }, - 'GLN': { - "1HB" : { - 'type':'H0', - 'hyb':'' - }, - "2HB" : { - 'type':'H0', - 'hyb':'' - }, - "1HG" : { - 'type':'H0', - 'hyb':'' - }, - "NE2" : { - 'type':'NH2', - 'hyb':'sp2' - }, - "OE1" : { - 'type':'O', - 'hyb':'sp2' - }, - "2HE2" : { - 'type':'H', - 'hyb':'' - }, - "CG" : { - 'type':'CH2E', - 'hyb':'sp3' - }, - "1HE2" : { - 'type':'H', - 'hyb':'' - }, - "2HG" : { - 'type':'H0', - 'hyb':'' - }, - "CD" : { - 'type':'C', - 'hyb':'sp2' - }, - }, - 'GLU': { - "1HB" : { - 'type':'H0', - 'hyb':'' - }, - "1HG" : { - 'type':'H0', - 'hyb':'' - }, - "HE2" : { - 'type':'H', - 'hyb':'' - }, - "OE2" : { - 'type':'OC', - 'hyb':'sp2' - }, - "OE1" : { - 'type':'OC', - 'hyb':'sp2' - }, - "2HB" : { - 'type':'H0', - 'hyb':'' - }, - "CG" : { - 'type':'CH2E', - 'hyb':'sp3' - }, - "2HG" : { - 'type':'H0', - 'hyb':'' - }, - "CD" : { - 'type':'C', - 'hyb':'sp2' - }, - }, - 'GLY': { - "2HA" : { - 'type':'HA', - 'hyb':'' - }, - "CA" : { - 'type':'CH2G', - 'hyb':'sp3' - }, - "1HA" : { - 'type':'HA', - 'hyb':'' - }, - }, - 'HIS': { - "HE2" : { - 'type':'H', - 'hyb':'' - }, - "HD2" : { - 'type':'HAR', - 'hyb':'' - }, - "HD1" : { - 'type':'H', - 'hyb':'' - }, - "CG" : { - 'type':'C5', - 'hyb':'sp2' - }, - "HE1" : { - 'type':'HAR', - 'hyb':'' - }, - "1HB" : { - 'type':'H0', - 'hyb':'' - }, - "CD2" : { - 'type':'CR1H', - 'hyb':'sp2' - }, - "ND1" : { - 'type':'NH1', - 'hyb':'sp2' - }, - "2HB" : { - 'type':'H0', - 'hyb':'' - }, - "NE2" : { - 'type':'NHS', - 'hyb':'sp2' - }, - "CE1" : { - 'type':'CRHH', - 'hyb':'sp2' - }, - }, - 'ILE': { - "2HG2" : { - 'type':'H0', - 'hyb':'' - }, - "2HG1" : { - 'type':'H0', - 'hyb':'' - }, - "CB" : { - 'type':'CH1E', - 'hyb':'sp3' - }, - "3HG2" : { - 'type':'H0', - 'hyb':'' - }, - "2HD1" : { - 'type':'H0', - 'hyb':'' - }, - "3HD1" : { - 'type':'H0', - 'hyb':'' - }, - "CG1" : { - 'type':'CH2E', - 'hyb':'sp3' - }, - "1HG2" : { - 'type':'H0', - 'hyb':'' - }, - "CD1" : { - 'type':'CH3E', - 'hyb':'sp3' - }, - "1HG1" : { - 'type':'H0', - 'hyb':'' - }, - "HB" : { - 'type':'H0', - 'hyb':'' - }, - "CG2" : { - 'type':'CH3E', - 'hyb':'sp3' - }, - "1HD1" : { - 'type':'H0', - 'hyb':'' - }, - }, - 'LEU': { - "1HB" : { - 'type':'H0', - 'hyb':'' - }, - "2HB" : { - 'type':'H0', - 'hyb':'' - }, - "1HD2" : { - 'type':'H0', - 'hyb':'' - }, - "1HD1" : { - 'type':'H0', - 'hyb':'' - }, - "CG" : { - 'type':'CH1E', - 'hyb':'sp3' - }, - "2HD2" : { - 'type':'H0', - 'hyb':'' - }, - "3HD1" : { - 'type':'H0', - 'hyb':'' - }, - "3HD2" : { - 'type':'H0', - 'hyb':'' - }, - "CD1" : { - 'type':'CH3E', - 'hyb':'sp3' - }, - "CD2" : { - 'type':'CH3E', - 'hyb':'sp3' - }, - "2HD1" : { - 'type':'H0', - 'hyb':'' - }, - "HG" : { - 'type':'H0', - 'hyb':'' - }, - }, - 'LYS': { - "2HZ" : { - 'type':'HC', - 'hyb':'' - }, - "1HZ" : { - 'type':'HC', - 'hyb':'' - }, - "3HZ" : { - 'type':'HC', - 'hyb':'' - }, - "CG" : { - 'type':'CH2E', - 'hyb':'sp3' - }, - "CE" : { - 'type':'CH2E', - 'hyb':'sp3' - }, - "CD" : { - 'type':'CH2E', - 'hyb':'sp3' - }, - "1HB" : { - 'type':'H0', - 'hyb':'' - }, - "NZ" : { - 'type':'NH3', - 'hyb':'sp3' - }, - "1HG" : { - 'type':'H0', - 'hyb':'' - }, - "1HD" : { - 'type':'H0', - 'hyb':'' - }, - "1HE" : { - 'type':'H0', - 'hyb':'' - }, - "2HB" : { - 'type':'H0', - 'hyb':'' - }, - "2HE" : { - 'type':'H0', - 'hyb':'' - }, - "2HD" : { - 'type':'H0', - 'hyb':'' - }, - "2HG" : { - 'type':'H0', - 'hyb':'' - }, - }, - 'LYSH': { - "2HZ" : { - 'type':'HC', - 'hyb':'' - }, - "1HZ" : { - 'type':'HC', - 'hyb':'' - }, - "3HZ" : { - 'type':'HC', - 'hyb':'' - }, - "CG" : { - 'type':'CH2E', - 'hyb':'sp3' - }, - "CE" : { - 'type':'CH2E', - 'hyb':'sp3' - }, - "CD" : { - 'type':'CH2E', - 'hyb':'sp3' - }, - "1HB" : { - 'type':'H0', - 'hyb':'' - }, - "NZ" : { - 'type':'NH3', - 'hyb':'sp3' - }, - "1HG" : { - 'type':'H0', - 'hyb':'' - }, - "1HD" : { - 'type':'H0', - 'hyb':'' - }, - "1HE" : { - 'type':'H0', - 'hyb':'' - }, - "2HB" : { - 'type':'H0', - 'hyb':'' - }, - "2HE" : { - 'type':'H0', - 'hyb':'' - }, - "2HD" : { - 'type':'H0', - 'hyb':'' - }, - "2HG" : { - 'type':'H0', - 'hyb':'' - }, - }, - 'MET': { - "1HB" : { - 'type':'H0', - 'hyb':'' - }, - "SD" : { - 'type':'SM', - 'hyb':'sp3' - }, - "2HG" : { - 'type':'H0', - 'hyb':'' - }, - "1HG" : { - 'type':'H0', - 'hyb':'' - }, - "1HE" : { - 'type':'H0', - 'hyb':'' - }, - "2HE" : { - 'type':'H0', - 'hyb':'' - }, - "2HB" : { - 'type':'H0', - 'hyb':'' - }, - "CG" : { - 'type':'CH2E', - 'hyb':'sp3' - }, - "CE" : { - 'type':'CH3E', - 'hyb':'sp3' - }, - "3HE" : { - 'type':'H0', - 'hyb':'' - }, - }, - 'PHE': { - "HZ" : { - 'type':'HAR', - 'hyb':'' - }, - "HD2" : { - 'type':'HAR', - 'hyb':'' - }, - "HE2" : { - 'type':'HAR', - 'hyb':'' - }, - "CZ" : { - 'type':'CR1E', - 'hyb':'sp2' - }, - "CE1" : { - 'type':'CR1E', - 'hyb':'sp2' - }, - "CG" : { - 'type':'CF', - 'hyb':'sp2' - }, - "1HB" : { - 'type':'H0', - 'hyb':'' - }, - "HD1" : { - 'type':'HAR', - 'hyb':'' - }, - "CE2" : { - 'type':'CR1E', - 'hyb':'sp2' - }, - "CD1" : { - 'type':'CR1E', - 'hyb':'sp2' - }, - "CD2" : { - 'type':'CR1E', - 'hyb':'sp2' - }, - "2HB" : { - 'type':'H0', - 'hyb':'' - }, - "HE1" : { - 'type':'HAR', - 'hyb':'' - }, - }, - 'PRO': { - "1HB" : { - 'type':'H0', - 'hyb':'' - }, - "1HG" : { - 'type':'H0', - 'hyb':'' - }, - "1HD" : { - 'type':'H0', - 'hyb':'' - }, - "CB" : { - 'type':'CH2P', - 'hyb':'sp3' - }, - "2HB" : { - 'type':'H0', - 'hyb':'' - }, - "CG" : { - 'type':'CH2P', - 'hyb':'sp3' - }, - "2HD" : { - 'type':'H0', - 'hyb':'' - }, - "2HG" : { - 'type':'H0', - 'hyb':'' - }, - "CD" : { - 'type':'CH2P', - 'hyb':'sp3' - }, - }, - 'SER': { - "OG" : { - 'type':'OH1', - 'hyb':'sp3' - }, - "1HB" : { - 'type':'H0', - 'hyb':'' - }, - "2HB" : { - 'type':'H0', - 'hyb':'' - }, - "HG" : { - 'type':'H', - 'hyb':'' - }, - }, - 'THR': { - "2HG2" : { - 'type':'H0', - 'hyb':'' - }, - "1HG2" : { - 'type':'H0', - 'hyb':'' - }, - "HB" : { - 'type':'H0', - 'hyb':'' - }, - "CB" : { - 'type':'CH1E', - 'hyb':'sp3' - }, - "3HG2" : { - 'type':'H0', - 'hyb':'' - }, - "CG2" : { - 'type':'CH3E', - 'hyb':'sp3' - }, - "OG1" : { - 'type':'OH1', - 'hyb':'sp3' - }, - "HG1" : { - 'type':'H', - 'hyb':'' - }, - }, - 'TRP': { - "HH2" : { - 'type':'HAR', - 'hyb':'' - }, - "CD1" : { - 'type':'CW', - 'hyb':'sp2' - }, - "HE1" : { - 'type':'H', - 'hyb':'' - }, - "HD1" : { - 'type':'HAR', - 'hyb':'' - }, - "HE3" : { - 'type':'HAR', - 'hyb':'' - }, - "CZ2" : { - 'type':'CR1W', - 'hyb':'sp2' - }, - "CZ3" : { - 'type':'CR1E', - 'hyb':'sp2' - }, - "CG" : { - 'type':'C5W', - 'hyb':'sp2' - }, - "1HB" : { - 'type':'H0', - 'hyb':'' - }, - "CH2" : { - 'type':'CR1W', - 'hyb':'sp2' - }, - "CE3" : { - 'type':'CR1E', - 'hyb':'sp2' - }, - "CE2" : { - 'type':'CW', - 'hyb':'sp2' - }, - "CD2" : { - 'type':'CR1E', - 'hyb':'sp2' - }, - "HZ2" : { - 'type':'HAR', - 'hyb':'' - }, - "2HB" : { - 'type':'H0', - 'hyb':'' - }, - "HZ3" : { - 'type':'HAR', - 'hyb':'' - }, - "NE1" : { - 'type':'NH1', - 'hyb':'sp2' - }, - }, - 'TYR': { - "HD2" : { - 'type':'HAR', - 'hyb':'' - }, - "HE2" : { - 'type':'HAR', - 'hyb':'' - }, - "OH" : { - 'type':'OH1', - 'hyb':'sp3' - }, - "CE1" : { - 'type':'CR1E', - 'hyb':'sp2' - }, - "CE2" : { - 'type':'CR1E', - 'hyb':'sp2' - }, - "CG" : { - 'type':'CY', - 'hyb':'sp2' - }, - "1HB" : { - 'type':'H0', - 'hyb':'' - }, - "CZ" : { - 'type':'CY2', - 'hyb':'sp2' - }, - "HH" : { - 'type':'H', - 'hyb':'' - }, - "CD1" : { - 'type':'CR1E', - 'hyb':'sp2' - }, - "CD2" : { - 'type':'CR1E', - 'hyb':'sp2' - }, - "HD1" : { - 'type':'HAR', - 'hyb':'' - }, - "2HB" : { - 'type':'H0', - 'hyb':'' - }, - "HE1" : { - 'type':'HAR', - 'hyb':'' - }, - }, - 'VAL': { - "CG1" : { - 'type':'CH3E', - 'hyb':'sp3' - }, - "2HG2" : { - 'type':'H0', - 'hyb':'' - }, - "2HG1" : { - 'type':'H0', - 'hyb':'' - }, - "CG2" : { - 'type':'CH3E', - 'hyb':'sp3' - }, - "1HG2" : { - 'type':'H0', - 'hyb':'' - }, - "3HG1" : { - 'type':'H0', - 'hyb':'' - }, - "HB" : { - 'type':'H0', - 'hyb':'' - }, - "CB" : { - 'type':'CH1E', - 'hyb':'sp3' - }, - "3HG2" : { - 'type':'H0', - 'hyb':'' - }, - "1HG1" : { - 'type':'H0', - 'hyb':'' - }, - }, - 'COO-': { - "OXT" : { - 'type':'OC', - 'hyb':'' - }, - }, - 'COOH': { - "OT" : { - 'type':'O', - 'hyb':'' - }, - "HO" : { - 'type':'H', - 'hyb':'' - }, - "O" : { - 'type':'OH1', - 'hyb':'' - }, - }, - 'NH3+': { - "1H" : { - 'type':'HC', - 'hyb':'' - }, - "3H" : { - 'type':'HC', - 'hyb':'' - }, - "2H" : { - 'type':'HC', - 'hyb':'' - }, - }, - 'NH2': { - "1H" : { - 'type':'H', - 'hyb':'' - }, - "2H" : { - 'type':'H', - 'hyb':'' - }, - "N" : { - 'type':'NHB', - 'hyb':'' - }, - }, - 'PRO-NH2+': { - "1H" : { - 'type':'HC', - 'hyb':'' - }, - "2H" : { - 'type':'HC', - 'hyb':'' - }, - }, - 'PRO-NH': { - "H" : { - 'type':'H', - 'hyb':'' - }, - "N" : { - 'type':'NHB', - 'hyb':'' - }, - }, - 'HISB': { - "ND1" : { - 'type':'NHS', - 'hyb':'' - }, - "NE2" : { - 'type':'NH1', - 'hyb':'' - }, - }, - 'HISH': { - "NE2" : { - 'type':'NH1', - 'hyb':'' - }, - "HE2" : { - 'type':'H', - 'hyb':'' - }, - }, - 'LYSN': { - "NZ" : { - 'type':'NH2', - 'hyb':'' - }, - "HZ1" : { - 'type':'H', - 'hyb':'' - }, - "HZ2" : { - 'type':'H', - 'hyb':'' - }, - }, - 'ASPH': { - "OD1" : { - 'type':'O', - 'hyb':'' - }, - "OD2" : { - 'type':'OH1', - 'hyb':'' - }, - "HD2" : { - 'type':'H', - 'hyb':'' - }, - }, - 'GLUH': { - "OE2" : { - 'type':'OH1', - 'hyb':'' - }, - "OE1" : { - 'type':'O', - 'hyb':'' - }, - "HE2" : { - 'type':'H', - 'hyb':'' - }, - }, - 'T': { - "H72" : { - 'type':'H0', - 'hyb':'' - }, - "OP1" : { - 'type':'OP', - 'hyb':'' - }, - "OP2" : { - 'type':'OP', - 'hyb':'' - }, - "'H2'" : { - 'type':'H0', - 'hyb':'' - }, - "C3'" : { - 'type':'C3S', - 'hyb':'' - }, - "C1'" : { - 'type':'C1S', - 'hyb':'' - }, - "C5'" : { - 'type':'C5S', - 'hyb':'' - }, - "P" : { - 'type':'PN', - 'hyb':'' - }, - "C4'" : { - 'type':'C4S', - 'hyb':'' - }, - "C2'" : { - 'type':'C2S', - 'hyb':'' - }, - "N1" : { - 'type':'N1T', - 'hyb':'' - }, - "H2'" : { - 'type':'H0', - 'hyb':'' - }, - "N3" : { - 'type':'N3T', - 'hyb':'' - }, - "O2" : { - 'type':'O2T', - 'hyb':'' - }, - "H71" : { - 'type':'H0', - 'hyb':'' - }, - "H3'" : { - 'type':'H0', - 'hyb':'' - }, - "H4'" : { - 'type':'H0', - 'hyb':'' - }, - "H73" : { - 'type':'H0', - 'hyb':'' - }, - "O4" : { - 'type':'O4T', - 'hyb':'' - }, - "'H5'" : { - 'type':'H0', - 'hyb':'' - }, - "H3" : { - 'type':'H', - 'hyb':'' - }, - "O5'" : { - 'type':'O5S', - 'hyb':'' - }, - "O4'" : { - 'type':'O4S', - 'hyb':'' - }, - "H5'" : { - 'type':'H0', - 'hyb':'' - }, - "H6" : { - 'type':'H0', - 'hyb':'' - }, - "O3'" : { - 'type':'O3S', - 'hyb':'' - }, - "C2" : { - 'type':'C2T', - 'hyb':'' - }, - "H1'" : { - 'type':'H0', - 'hyb':'' - }, - "C7" : { - 'type':'C7T', - 'hyb':'' - }, - "C6" : { - 'type':'C6T', - 'hyb':'' - }, - "C5" : { - 'type':'C5T', - 'hyb':'' - }, - "C4" : { - 'type':'C4T', - 'hyb':'' - }, - }, - 'A': { - "OP1" : { - 'type':'OP', - 'hyb':'' - }, - "OP2" : { - 'type':'OP', - 'hyb':'' - }, - "H62" : { - 'type':'H', - 'hyb':'' - }, - "H3'" : { - 'type':'H0', - 'hyb':'' - }, - "C3'" : { - 'type':'C3S', - 'hyb':'' - }, - "C1'" : { - 'type':'C1S', - 'hyb':'' - }, - "C5'" : { - 'type':'C5S', - 'hyb':'' - }, - "N9" : { - 'type':'N9A', - 'hyb':'' - }, - "C4'" : { - 'type':'C4S', - 'hyb':'' - }, - "C2'" : { - 'type':'C2S', - 'hyb':'' - }, - "N1" : { - 'type':'N1A', - 'hyb':'' - }, - "H2'" : { - 'type':'H0', - 'hyb':'' - }, - "N3" : { - 'type':'N3A', - 'hyb':'' - }, - "N6" : { - 'type':'N6A', - 'hyb':'' - }, - "N7" : { - 'type':'N7A', - 'hyb':'' - }, - "H4'" : { - 'type':'H0', - 'hyb':'' - }, - "'H2'" : { - 'type':'H0', - 'hyb':'' - }, - "H8" : { - 'type':'H0', - 'hyb':'' - }, - "H5'" : { - 'type':'H0', - 'hyb':'' - }, - "'H5'" : { - 'type':'H0', - 'hyb':'' - }, - "P" : { - 'type':'PN', - 'hyb':'' - }, - "H2" : { - 'type':'H0', - 'hyb':'' - }, - "O5'" : { - 'type':'O5S', - 'hyb':'' - }, - "O4'" : { - 'type':'O4S', - 'hyb':'' - }, - "C8" : { - 'type':'C8A', - 'hyb':'' - }, - "O3'" : { - 'type':'O3S', - 'hyb':'' - }, - "H61" : { - 'type':'H', - 'hyb':'' - }, - "C2" : { - 'type':'C2A', - 'hyb':'' - }, - "H1'" : { - 'type':'H0', - 'hyb':'' - }, - "C6" : { - 'type':'C6A', - 'hyb':'' - }, - "C5" : { - 'type':'C5A', - 'hyb':'' - }, - "C4" : { - 'type':'C4A', - 'hyb':'' - }, - }, - 'G': { - "OP1" : { - 'type':'OP', - 'hyb':'' - }, - "OP2" : { - 'type':'OP', - 'hyb':'' - }, - "H3'" : { - 'type':'H0', - 'hyb':'' - }, - "C3'" : { - 'type':'C3S', - 'hyb':'' - }, - "C1'" : { - 'type':'C1S', - 'hyb':'' - }, - "H21" : { - 'type':'H', - 'hyb':'' - }, - "C5'" : { - 'type':'C5S', - 'hyb':'' - }, - "N9" : { - 'type':'N9G', - 'hyb':'' - }, - "C4'" : { - 'type':'C4S', - 'hyb':'' - }, - "C2'" : { - 'type':'C2S', - 'hyb':'' - }, - "O6" : { - 'type':'O6G', - 'hyb':'' - }, - "N1" : { - 'type':'N1G', - 'hyb':'' - }, - "N2" : { - 'type':'N2G', - 'hyb':'' - }, - "N3" : { - 'type':'N3G', - 'hyb':'' - }, - "H2'" : { - 'type':'H0', - 'hyb':'' - }, - "N7" : { - 'type':'N7G', - 'hyb':'' - }, - "H4'" : { - 'type':'H0', - 'hyb':'' - }, - "'H2'" : { - 'type':'H0', - 'hyb':'' - }, - "H8" : { - 'type':'H0', - 'hyb':'' - }, - "H5'" : { - 'type':'H0', - 'hyb':'' - }, - "'H5'" : { - 'type':'H0', - 'hyb':'' - }, - "P" : { - 'type':'PN', - 'hyb':'' - }, - "H1" : { - 'type':'H', - 'hyb':'' - }, - "O5'" : { - 'type':'O5S', - 'hyb':'' - }, - "O4'" : { - 'type':'O4S', - 'hyb':'' - }, - "H22" : { - 'type':'H', - 'hyb':'' - }, - "C8" : { - 'type':'C8G', - 'hyb':'' - }, - "O3'" : { - 'type':'O3S', - 'hyb':'' - }, - "C2" : { - 'type':'C2G', - 'hyb':'' - }, - "H1'" : { - 'type':'H0', - 'hyb':'' - }, - "C6" : { - 'type':'C6G', - 'hyb':'' - }, - "C5" : { - 'type':'C5G', - 'hyb':'' - }, - "C4" : { - 'type':'C4G', - 'hyb':'' - }, - }, - 'C': { - "OP1" : { - 'type':'OP', - 'hyb':'' - }, - "OP2" : { - 'type':'OP', - 'hyb':'' - }, - "'H2'" : { - 'type':'H0', - 'hyb':'' - }, - "C3'" : { - 'type':'C3S', - 'hyb':'' - }, - "C1'" : { - 'type':'C1S', - 'hyb':'' - }, - "C5'" : { - 'type':'C5S', - 'hyb':'' - }, - "P" : { - 'type':'PN', - 'hyb':'' - }, - "C4'" : { - 'type':'C4S', - 'hyb':'' - }, - "C2'" : { - 'type':'C2S', - 'hyb':'' - }, - "N1" : { - 'type':'N1C', - 'hyb':'' - }, - "H2'" : { - 'type':'H0', - 'hyb':'' - }, - "N3" : { - 'type':'N3C', - 'hyb':'' - }, - "N4" : { - 'type':'N4C', - 'hyb':'' - }, - "O2" : { - 'type':'O2C', - 'hyb':'' - }, - "H3'" : { - 'type':'H0', - 'hyb':'' - }, - "H4'" : { - 'type':'H0', - 'hyb':'' - }, - "H42" : { - 'type':'H', - 'hyb':'' - }, - "H5'" : { - 'type':'H0', - 'hyb':'' - }, - "'H5'" : { - 'type':'H0', - 'hyb':'' - }, - "O5'" : { - 'type':'O5S', - 'hyb':'' - }, - "H5" : { - 'type':'H0', - 'hyb':'' - }, - "O4'" : { - 'type':'O4S', - 'hyb':'' - }, - "H6" : { - 'type':'H0', - 'hyb':'' - }, - "O3'" : { - 'type':'O3S', - 'hyb':'' - }, - "H41" : { - 'type':'H', - 'hyb':'' - }, - "C2" : { - 'type':'C2C', - 'hyb':'' - }, - "H1'" : { - 'type':'H0', - 'hyb':'' - }, - "C6" : { - 'type':'C6C', - 'hyb':'' - }, - "C5" : { - 'type':'C5C', - 'hyb':'' - }, - "C4" : { - 'type':'C4C', - 'hyb':'' - }, - }, - 'HOH': { - "H2" : { - 'type':'HWAT', - 'hyb':'' - }, - "H1" : { - 'type':'HWAT', - 'hyb':'' - }, - "O" : { - 'type':'OWAT', - 'hyb':'' - }, - }, - 'SOL': { - "MW" : { - 'type':'MWAT', - 'hyb':'' - }, - "OW4" : { - 'type':'OWAT', - 'hyb':'' - }, - "OW" : { - 'type':'OWAT', - 'hyb':'' - }, - "MW1" : { - 'type':'MWAT', - 'hyb':'' - }, - "HW2" : { - 'type':'HWAT', - 'hyb':'' - }, - "HW3" : { - 'type':'HWAT', - 'hyb':'' - }, - "HW1" : { - 'type':'HWAT', - 'hyb':'' - }, - }, - 'NA': { - "NA" : { - 'type':'NA', - 'hyb':'' - }, - }, - 'MG': { - "MG" : { - 'type':'MG', - 'hyb':'' - }, - }, - 'CA': { - "CA" : { - 'type':'CAL', - 'hyb':'' - }, - }, - 'K': { - "K" : { - 'type':'K', - 'hyb':'' - }, - }, - 'ZN': { - "ZN" : { - 'type':'ZN', - 'hyb':'' - }, - }, - 'FE': { - "FE" : { - 'type':'FE', - 'hyb':'' - }, - }, - 'MN': { - "MN" : { - 'type':'MN', - 'hyb':'' - }, - }, - 'SO4': { - "S" : { - 'type':'SUL', - 'hyb':'' - }, - "O4" : { - 'type':'OSUL', - 'hyb':'' - }, - "O3" : { - 'type':'OSUL', - 'hyb':'' - }, - "O2" : { - 'type':'OSUL', - 'hyb':'' - }, - "O1" : { - 'type':'OSUL', - 'hyb':'' - }, - }, - 'CL-': { - "CL" : { - 'type':'CL', - 'hyb':'' - }, - }, + "O\'" : { + 'type':'OC', + 'hyb':'' + }, + "O\'\'" : { + 'type':'OC', + 'hyb':'' + }, + "H" : { + 'type':'H', + 'hyb':'' + }, + "1H" : { + 'type':'HC', + 'hyb':'' + }, + "2H" : { + 'type':'HC', + 'hyb':'' + }, + "3H" : { + 'type':'HC', + 'hyb':'' + }, + "CA" : { + 'type':'CA', + 'hyb':'sp3' + }, + "HA" : { + 'type':'HA', + 'hyb':'' + }, + "O" : { + 'type':'O', + 'hyb':'' + }, + "N" : { + 'type':'NH1', + 'hyb':'sp2' + }, + }, + 'ALA': { + "1HB" : { + 'type':'H0', + 'hyb':'' + }, + "CB" : { + 'type':'CH3E', + 'hyb':'sp3' + }, + "3HB" : { + 'type':'H0', + 'hyb':'' + }, + "2HB" : { + 'type':'H0', + 'hyb':'' + }, + }, + 'ARG': { + "2HH2" : { + 'type':'HC', + 'hyb':'' + }, + "2HD" : { + 'type':'HDR', + 'hyb':'' + }, + "2HH1" : { + 'type':'HC', + 'hyb':'' + }, + "CG" : { + 'type':'CH2E', + 'hyb':'sp3' + }, + "NE" : { + 'type':'NH1', + 'hyb':'sp2' + }, + "CD" : { + 'type':'CDR', + 'hyb':'sp3' + }, + "1HB" : { + 'type':'H0', + 'hyb':'' + }, + "CZ" : { + 'type':'C', + 'hyb':'sp2' + }, + "2HG" : { + 'type':'H0', + 'hyb':'' + }, + "NH1" : { + 'type':'NC2', + 'hyb':'sp2' + }, + "1HG" : { + 'type':'H0', + 'hyb':'' + }, + "1HD" : { + 'type':'HDR', + 'hyb':'' + }, + "NH2" : { + 'type':'NC2', + 'hyb':'sp2' + }, + "2HB" : { + 'type':'H0', + 'hyb':'' + }, + "1HH2" : { + 'type':'HC', + 'hyb':'' + }, + "1HH1" : { + 'type':'HC', + 'hyb':'' + }, + "HE" : { + 'type':'H', + 'hyb':'' + }, + }, + 'ASN': { + "1HB" : { + 'type':'H0', + 'hyb':'' + }, + "ND2" : { + 'type':'NH2', + 'hyb':'sp2' + }, + "1HD2" : { + 'type':'H', + 'hyb':'' + }, + "OD1" : { + 'type':'O', + 'hyb':'sp2' + }, + "2HB" : { + 'type':'H0', + 'hyb':'' + }, + "CG" : { + 'type':'C', + 'hyb':'sp2' + }, + "2HD2" : { + 'type':'H', + 'hyb':'' + }, + }, + 'ASP': { + "1HB" : { + 'type':'H0', + 'hyb':'' + }, + "HD2" : { + 'type':'H', + 'hyb':'' + }, + "OD1" : { + 'type':'OC', + 'hyb':'sp2' + }, + "OD2" : { + 'type':'OC', + 'hyb':'sp2' + }, + "2HB" : { + 'type':'H0', + 'hyb':'' + }, + "CG" : { + 'type':'C', + 'hyb':'sp2' + }, + }, + 'CYS': { + "1HB" : { + 'type':'H0', + 'hyb':'' + }, + "2HB" : { + 'type':'H0', + 'hyb':'' + }, + "SG" : { + 'type':'S', + 'hyb':'sp3' + }, + "HG" : { + 'type':'H0', + 'hyb':'' + }, + }, + 'GLN': { + "1HB" : { + 'type':'H0', + 'hyb':'' + }, + "2HB" : { + 'type':'H0', + 'hyb':'' + }, + "1HG" : { + 'type':'H0', + 'hyb':'' + }, + "NE2" : { + 'type':'NH2', + 'hyb':'sp2' + }, + "OE1" : { + 'type':'O', + 'hyb':'sp2' + }, + "2HE2" : { + 'type':'H', + 'hyb':'' + }, + "CG" : { + 'type':'CH2E', + 'hyb':'sp3' + }, + "1HE2" : { + 'type':'H', + 'hyb':'' + }, + "2HG" : { + 'type':'H0', + 'hyb':'' + }, + "CD" : { + 'type':'C', + 'hyb':'sp2' + }, + }, + 'GLU': { + "1HB" : { + 'type':'H0', + 'hyb':'' + }, + "1HG" : { + 'type':'H0', + 'hyb':'' + }, + "HE2" : { + 'type':'H', + 'hyb':'' + }, + "OE2" : { + 'type':'OC', + 'hyb':'sp2' + }, + "OE1" : { + 'type':'OC', + 'hyb':'sp2' + }, + "2HB" : { + 'type':'H0', + 'hyb':'' + }, + "CG" : { + 'type':'CH2E', + 'hyb':'sp3' + }, + "2HG" : { + 'type':'H0', + 'hyb':'' + }, + "CD" : { + 'type':'C', + 'hyb':'sp2' + }, + }, + 'GLY': { + "2HA" : { + 'type':'HA', + 'hyb':'' + }, + "CA" : { + 'type':'CH2G', + 'hyb':'sp3' + }, + "1HA" : { + 'type':'HA', + 'hyb':'' + }, + }, + 'HIS': { + "HE2" : { + 'type':'H', + 'hyb':'' + }, + "HD2" : { + 'type':'HAR', + 'hyb':'' + }, + "HD1" : { + 'type':'H', + 'hyb':'' + }, + "CG" : { + 'type':'C5', + 'hyb':'sp2' + }, + "HE1" : { + 'type':'HAR', + 'hyb':'' + }, + "1HB" : { + 'type':'H0', + 'hyb':'' + }, + "CD2" : { + 'type':'CR1H', + 'hyb':'sp2' + }, + "ND1" : { + 'type':'NH1', + 'hyb':'sp2' + }, + "2HB" : { + 'type':'H0', + 'hyb':'' + }, + "NE2" : { + 'type':'NHS', + 'hyb':'sp2' + }, + "CE1" : { + 'type':'CRHH', + 'hyb':'sp2' + }, + }, + 'ILE': { + "2HG2" : { + 'type':'H0', + 'hyb':'' + }, + "2HG1" : { + 'type':'H0', + 'hyb':'' + }, + "CB" : { + 'type':'CH1E', + 'hyb':'sp3' + }, + "3HG2" : { + 'type':'H0', + 'hyb':'' + }, + "2HD1" : { + 'type':'H0', + 'hyb':'' + }, + "3HD1" : { + 'type':'H0', + 'hyb':'' + }, + "CG1" : { + 'type':'CH2E', + 'hyb':'sp3' + }, + "1HG2" : { + 'type':'H0', + 'hyb':'' + }, + "CD1" : { + 'type':'CH3E', + 'hyb':'sp3' + }, + "1HG1" : { + 'type':'H0', + 'hyb':'' + }, + "HB" : { + 'type':'H0', + 'hyb':'' + }, + "CG2" : { + 'type':'CH3E', + 'hyb':'sp3' + }, + "1HD1" : { + 'type':'H0', + 'hyb':'' + }, + }, + 'LEU': { + "1HB" : { + 'type':'H0', + 'hyb':'' + }, + "2HB" : { + 'type':'H0', + 'hyb':'' + }, + "1HD2" : { + 'type':'H0', + 'hyb':'' + }, + "1HD1" : { + 'type':'H0', + 'hyb':'' + }, + "CG" : { + 'type':'CH1E', + 'hyb':'sp3' + }, + "2HD2" : { + 'type':'H0', + 'hyb':'' + }, + "3HD1" : { + 'type':'H0', + 'hyb':'' + }, + "3HD2" : { + 'type':'H0', + 'hyb':'' + }, + "CD1" : { + 'type':'CH3E', + 'hyb':'sp3' + }, + "CD2" : { + 'type':'CH3E', + 'hyb':'sp3' + }, + "2HD1" : { + 'type':'H0', + 'hyb':'' + }, + "HG" : { + 'type':'H0', + 'hyb':'' + }, + }, + 'LYS': { + "2HZ" : { + 'type':'HC', + 'hyb':'' + }, + "1HZ" : { + 'type':'HC', + 'hyb':'' + }, + "3HZ" : { + 'type':'HC', + 'hyb':'' + }, + "CG" : { + 'type':'CH2E', + 'hyb':'sp3' + }, + "CE" : { + 'type':'CH2E', + 'hyb':'sp3' + }, + "CD" : { + 'type':'CH2E', + 'hyb':'sp3' + }, + "1HB" : { + 'type':'H0', + 'hyb':'' + }, + "NZ" : { + 'type':'NH3', + 'hyb':'sp3' + }, + "1HG" : { + 'type':'H0', + 'hyb':'' + }, + "1HD" : { + 'type':'H0', + 'hyb':'' + }, + "1HE" : { + 'type':'H0', + 'hyb':'' + }, + "2HB" : { + 'type':'H0', + 'hyb':'' + }, + "2HE" : { + 'type':'H0', + 'hyb':'' + }, + "2HD" : { + 'type':'H0', + 'hyb':'' + }, + "2HG" : { + 'type':'H0', + 'hyb':'' + }, + }, + 'LYSH': { + "2HZ" : { + 'type':'HC', + 'hyb':'' + }, + "1HZ" : { + 'type':'HC', + 'hyb':'' + }, + "3HZ" : { + 'type':'HC', + 'hyb':'' + }, + "CG" : { + 'type':'CH2E', + 'hyb':'sp3' + }, + "CE" : { + 'type':'CH2E', + 'hyb':'sp3' + }, + "CD" : { + 'type':'CH2E', + 'hyb':'sp3' + }, + "1HB" : { + 'type':'H0', + 'hyb':'' + }, + "NZ" : { + 'type':'NH3', + 'hyb':'sp3' + }, + "1HG" : { + 'type':'H0', + 'hyb':'' + }, + "1HD" : { + 'type':'H0', + 'hyb':'' + }, + "1HE" : { + 'type':'H0', + 'hyb':'' + }, + "2HB" : { + 'type':'H0', + 'hyb':'' + }, + "2HE" : { + 'type':'H0', + 'hyb':'' + }, + "2HD" : { + 'type':'H0', + 'hyb':'' + }, + "2HG" : { + 'type':'H0', + 'hyb':'' + }, + }, + 'MET': { + "1HB" : { + 'type':'H0', + 'hyb':'' + }, + "SD" : { + 'type':'SM', + 'hyb':'sp3' + }, + "2HG" : { + 'type':'H0', + 'hyb':'' + }, + "1HG" : { + 'type':'H0', + 'hyb':'' + }, + "1HE" : { + 'type':'H0', + 'hyb':'' + }, + "2HE" : { + 'type':'H0', + 'hyb':'' + }, + "2HB" : { + 'type':'H0', + 'hyb':'' + }, + "CG" : { + 'type':'CH2E', + 'hyb':'sp3' + }, + "CE" : { + 'type':'CH3E', + 'hyb':'sp3' + }, + "3HE" : { + 'type':'H0', + 'hyb':'' + }, + }, + 'PHE': { + "HZ" : { + 'type':'HAR', + 'hyb':'' + }, + "HD2" : { + 'type':'HAR', + 'hyb':'' + }, + "HE2" : { + 'type':'HAR', + 'hyb':'' + }, + "CZ" : { + 'type':'CR1E', + 'hyb':'sp2' + }, + "CE1" : { + 'type':'CR1E', + 'hyb':'sp2' + }, + "CG" : { + 'type':'CF', + 'hyb':'sp2' + }, + "1HB" : { + 'type':'H0', + 'hyb':'' + }, + "HD1" : { + 'type':'HAR', + 'hyb':'' + }, + "CE2" : { + 'type':'CR1E', + 'hyb':'sp2' + }, + "CD1" : { + 'type':'CR1E', + 'hyb':'sp2' + }, + "CD2" : { + 'type':'CR1E', + 'hyb':'sp2' + }, + "2HB" : { + 'type':'H0', + 'hyb':'' + }, + "HE1" : { + 'type':'HAR', + 'hyb':'' + }, + }, + 'PRO': { + "1HB" : { + 'type':'H0', + 'hyb':'' + }, + "1HG" : { + 'type':'H0', + 'hyb':'' + }, + "1HD" : { + 'type':'H0', + 'hyb':'' + }, + "CB" : { + 'type':'CH2P', + 'hyb':'sp3' + }, + "2HB" : { + 'type':'H0', + 'hyb':'' + }, + "CG" : { + 'type':'CH2P', + 'hyb':'sp3' + }, + "2HD" : { + 'type':'H0', + 'hyb':'' + }, + "2HG" : { + 'type':'H0', + 'hyb':'' + }, + "CD" : { + 'type':'CH2P', + 'hyb':'sp3' + }, + }, + 'SER': { + "OG" : { + 'type':'OH1', + 'hyb':'sp3' + }, + "1HB" : { + 'type':'H0', + 'hyb':'' + }, + "2HB" : { + 'type':'H0', + 'hyb':'' + }, + "HG" : { + 'type':'H', + 'hyb':'' + }, + }, + 'THR': { + "2HG2" : { + 'type':'H0', + 'hyb':'' + }, + "1HG2" : { + 'type':'H0', + 'hyb':'' + }, + "HB" : { + 'type':'H0', + 'hyb':'' + }, + "CB" : { + 'type':'CH1E', + 'hyb':'sp3' + }, + "3HG2" : { + 'type':'H0', + 'hyb':'' + }, + "CG2" : { + 'type':'CH3E', + 'hyb':'sp3' + }, + "OG1" : { + 'type':'OH1', + 'hyb':'sp3' + }, + "HG1" : { + 'type':'H', + 'hyb':'' + }, + }, + 'TRP': { + "HH2" : { + 'type':'HAR', + 'hyb':'' + }, + "CD1" : { + 'type':'CW', + 'hyb':'sp2' + }, + "HE1" : { + 'type':'H', + 'hyb':'' + }, + "HD1" : { + 'type':'HAR', + 'hyb':'' + }, + "HE3" : { + 'type':'HAR', + 'hyb':'' + }, + "CZ2" : { + 'type':'CR1W', + 'hyb':'sp2' + }, + "CZ3" : { + 'type':'CR1E', + 'hyb':'sp2' + }, + "CG" : { + 'type':'C5W', + 'hyb':'sp2' + }, + "1HB" : { + 'type':'H0', + 'hyb':'' + }, + "CH2" : { + 'type':'CR1W', + 'hyb':'sp2' + }, + "CE3" : { + 'type':'CR1E', + 'hyb':'sp2' + }, + "CE2" : { + 'type':'CW', + 'hyb':'sp2' + }, + "CD2" : { + 'type':'CR1E', + 'hyb':'sp2' + }, + "HZ2" : { + 'type':'HAR', + 'hyb':'' + }, + "2HB" : { + 'type':'H0', + 'hyb':'' + }, + "HZ3" : { + 'type':'HAR', + 'hyb':'' + }, + "NE1" : { + 'type':'NH1', + 'hyb':'sp2' + }, + }, + 'TYR': { + "HD2" : { + 'type':'HAR', + 'hyb':'' + }, + "HE2" : { + 'type':'HAR', + 'hyb':'' + }, + "OH" : { + 'type':'OH1', + 'hyb':'sp3' + }, + "CE1" : { + 'type':'CR1E', + 'hyb':'sp2' + }, + "CE2" : { + 'type':'CR1E', + 'hyb':'sp2' + }, + "CG" : { + 'type':'CY', + 'hyb':'sp2' + }, + "1HB" : { + 'type':'H0', + 'hyb':'' + }, + "CZ" : { + 'type':'CY2', + 'hyb':'sp2' + }, + "HH" : { + 'type':'H', + 'hyb':'' + }, + "CD1" : { + 'type':'CR1E', + 'hyb':'sp2' + }, + "CD2" : { + 'type':'CR1E', + 'hyb':'sp2' + }, + "HD1" : { + 'type':'HAR', + 'hyb':'' + }, + "2HB" : { + 'type':'H0', + 'hyb':'' + }, + "HE1" : { + 'type':'HAR', + 'hyb':'' + }, + }, + 'VAL': { + "CG1" : { + 'type':'CH3E', + 'hyb':'sp3' + }, + "2HG2" : { + 'type':'H0', + 'hyb':'' + }, + "2HG1" : { + 'type':'H0', + 'hyb':'' + }, + "CG2" : { + 'type':'CH3E', + 'hyb':'sp3' + }, + "1HG2" : { + 'type':'H0', + 'hyb':'' + }, + "3HG1" : { + 'type':'H0', + 'hyb':'' + }, + "HB" : { + 'type':'H0', + 'hyb':'' + }, + "CB" : { + 'type':'CH1E', + 'hyb':'sp3' + }, + "3HG2" : { + 'type':'H0', + 'hyb':'' + }, + "1HG1" : { + 'type':'H0', + 'hyb':'' + }, + }, + 'COO-': { + "OXT" : { + 'type':'OC', + 'hyb':'' + }, + }, + 'COOH': { + "OT" : { + 'type':'O', + 'hyb':'' + }, + "HO" : { + 'type':'H', + 'hyb':'' + }, + "O" : { + 'type':'OH1', + 'hyb':'' + }, + }, + 'NH3+': { + "1H" : { + 'type':'HC', + 'hyb':'' + }, + "3H" : { + 'type':'HC', + 'hyb':'' + }, + "2H" : { + 'type':'HC', + 'hyb':'' + }, + }, + 'NH2': { + "1H" : { + 'type':'H', + 'hyb':'' + }, + "2H" : { + 'type':'H', + 'hyb':'' + }, + "N" : { + 'type':'NHB', + 'hyb':'' + }, + }, + 'PRO-NH2+': { + "1H" : { + 'type':'HC', + 'hyb':'' + }, + "2H" : { + 'type':'HC', + 'hyb':'' + }, + }, + 'PRO-NH': { + "H" : { + 'type':'H', + 'hyb':'' + }, + "N" : { + 'type':'NHB', + 'hyb':'' + }, + }, + 'HISB': { + "ND1" : { + 'type':'NHS', + 'hyb':'' + }, + "NE2" : { + 'type':'NH1', + 'hyb':'' + }, + }, + 'HISH': { + "NE2" : { + 'type':'NH1', + 'hyb':'' + }, + "HE2" : { + 'type':'H', + 'hyb':'' + }, + }, + 'LYSN': { + "NZ" : { + 'type':'NH2', + 'hyb':'' + }, + "HZ1" : { + 'type':'H', + 'hyb':'' + }, + "HZ2" : { + 'type':'H', + 'hyb':'' + }, + }, + 'ASPH': { + "OD1" : { + 'type':'O', + 'hyb':'' + }, + "OD2" : { + 'type':'OH1', + 'hyb':'' + }, + "HD2" : { + 'type':'H', + 'hyb':'' + }, + }, + 'GLUH': { + "OE2" : { + 'type':'OH1', + 'hyb':'' + }, + "OE1" : { + 'type':'O', + 'hyb':'' + }, + "HE2" : { + 'type':'H', + 'hyb':'' + }, + }, + 'T': { + "H72" : { + 'type':'H0', + 'hyb':'' + }, + "OP1" : { + 'type':'OP', + 'hyb':'' + }, + "OP2" : { + 'type':'OP', + 'hyb':'' + }, + "'H2'" : { + 'type':'H0', + 'hyb':'' + }, + "C3'" : { + 'type':'C3S', + 'hyb':'' + }, + "C1'" : { + 'type':'C1S', + 'hyb':'' + }, + "C5'" : { + 'type':'C5S', + 'hyb':'' + }, + "P" : { + 'type':'PN', + 'hyb':'' + }, + "C4'" : { + 'type':'C4S', + 'hyb':'' + }, + "C2'" : { + 'type':'C2S', + 'hyb':'' + }, + "N1" : { + 'type':'N1T', + 'hyb':'' + }, + "H2'" : { + 'type':'H0', + 'hyb':'' + }, + "N3" : { + 'type':'N3T', + 'hyb':'' + }, + "O2" : { + 'type':'O2T', + 'hyb':'' + }, + "H71" : { + 'type':'H0', + 'hyb':'' + }, + "H3'" : { + 'type':'H0', + 'hyb':'' + }, + "H4'" : { + 'type':'H0', + 'hyb':'' + }, + "H73" : { + 'type':'H0', + 'hyb':'' + }, + "O4" : { + 'type':'O4T', + 'hyb':'' + }, + "'H5'" : { + 'type':'H0', + 'hyb':'' + }, + "H3" : { + 'type':'H', + 'hyb':'' + }, + "O5'" : { + 'type':'O5S', + 'hyb':'' + }, + "O4'" : { + 'type':'O4S', + 'hyb':'' + }, + "H5'" : { + 'type':'H0', + 'hyb':'' + }, + "H6" : { + 'type':'H0', + 'hyb':'' + }, + "O3'" : { + 'type':'O3S', + 'hyb':'' + }, + "C2" : { + 'type':'C2T', + 'hyb':'' + }, + "H1'" : { + 'type':'H0', + 'hyb':'' + }, + "C7" : { + 'type':'C7T', + 'hyb':'' + }, + "C6" : { + 'type':'C6T', + 'hyb':'' + }, + "C5" : { + 'type':'C5T', + 'hyb':'' + }, + "C4" : { + 'type':'C4T', + 'hyb':'' + }, + }, + 'A': { + "OP1" : { + 'type':'OP', + 'hyb':'' + }, + "OP2" : { + 'type':'OP', + 'hyb':'' + }, + "H62" : { + 'type':'H', + 'hyb':'' + }, + "H3'" : { + 'type':'H0', + 'hyb':'' + }, + "C3'" : { + 'type':'C3S', + 'hyb':'' + }, + "C1'" : { + 'type':'C1S', + 'hyb':'' + }, + "C5'" : { + 'type':'C5S', + 'hyb':'' + }, + "N9" : { + 'type':'N9A', + 'hyb':'' + }, + "C4'" : { + 'type':'C4S', + 'hyb':'' + }, + "C2'" : { + 'type':'C2S', + 'hyb':'' + }, + "N1" : { + 'type':'N1A', + 'hyb':'' + }, + "H2'" : { + 'type':'H0', + 'hyb':'' + }, + "N3" : { + 'type':'N3A', + 'hyb':'' + }, + "N6" : { + 'type':'N6A', + 'hyb':'' + }, + "N7" : { + 'type':'N7A', + 'hyb':'' + }, + "H4'" : { + 'type':'H0', + 'hyb':'' + }, + "'H2'" : { + 'type':'H0', + 'hyb':'' + }, + "H8" : { + 'type':'H0', + 'hyb':'' + }, + "H5'" : { + 'type':'H0', + 'hyb':'' + }, + "'H5'" : { + 'type':'H0', + 'hyb':'' + }, + "P" : { + 'type':'PN', + 'hyb':'' + }, + "H2" : { + 'type':'H0', + 'hyb':'' + }, + "O5'" : { + 'type':'O5S', + 'hyb':'' + }, + "O4'" : { + 'type':'O4S', + 'hyb':'' + }, + "C8" : { + 'type':'C8A', + 'hyb':'' + }, + "O3'" : { + 'type':'O3S', + 'hyb':'' + }, + "H61" : { + 'type':'H', + 'hyb':'' + }, + "C2" : { + 'type':'C2A', + 'hyb':'' + }, + "H1'" : { + 'type':'H0', + 'hyb':'' + }, + "C6" : { + 'type':'C6A', + 'hyb':'' + }, + "C5" : { + 'type':'C5A', + 'hyb':'' + }, + "C4" : { + 'type':'C4A', + 'hyb':'' + }, + }, + 'G': { + "OP1" : { + 'type':'OP', + 'hyb':'' + }, + "OP2" : { + 'type':'OP', + 'hyb':'' + }, + "H3'" : { + 'type':'H0', + 'hyb':'' + }, + "C3'" : { + 'type':'C3S', + 'hyb':'' + }, + "C1'" : { + 'type':'C1S', + 'hyb':'' + }, + "H21" : { + 'type':'H', + 'hyb':'' + }, + "C5'" : { + 'type':'C5S', + 'hyb':'' + }, + "N9" : { + 'type':'N9G', + 'hyb':'' + }, + "C4'" : { + 'type':'C4S', + 'hyb':'' + }, + "C2'" : { + 'type':'C2S', + 'hyb':'' + }, + "O6" : { + 'type':'O6G', + 'hyb':'' + }, + "N1" : { + 'type':'N1G', + 'hyb':'' + }, + "N2" : { + 'type':'N2G', + 'hyb':'' + }, + "N3" : { + 'type':'N3G', + 'hyb':'' + }, + "H2'" : { + 'type':'H0', + 'hyb':'' + }, + "N7" : { + 'type':'N7G', + 'hyb':'' + }, + "H4'" : { + 'type':'H0', + 'hyb':'' + }, + "'H2'" : { + 'type':'H0', + 'hyb':'' + }, + "H8" : { + 'type':'H0', + 'hyb':'' + }, + "H5'" : { + 'type':'H0', + 'hyb':'' + }, + "'H5'" : { + 'type':'H0', + 'hyb':'' + }, + "P" : { + 'type':'PN', + 'hyb':'' + }, + "H1" : { + 'type':'H', + 'hyb':'' + }, + "O5'" : { + 'type':'O5S', + 'hyb':'' + }, + "O4'" : { + 'type':'O4S', + 'hyb':'' + }, + "H22" : { + 'type':'H', + 'hyb':'' + }, + "C8" : { + 'type':'C8G', + 'hyb':'' + }, + "O3'" : { + 'type':'O3S', + 'hyb':'' + }, + "C2" : { + 'type':'C2G', + 'hyb':'' + }, + "H1'" : { + 'type':'H0', + 'hyb':'' + }, + "C6" : { + 'type':'C6G', + 'hyb':'' + }, + "C5" : { + 'type':'C5G', + 'hyb':'' + }, + "C4" : { + 'type':'C4G', + 'hyb':'' + }, + }, + 'C': { + "OP1" : { + 'type':'OP', + 'hyb':'' + }, + "OP2" : { + 'type':'OP', + 'hyb':'' + }, + "'H2'" : { + 'type':'H0', + 'hyb':'' + }, + "C3'" : { + 'type':'C3S', + 'hyb':'' + }, + "C1'" : { + 'type':'C1S', + 'hyb':'' + }, + "C5'" : { + 'type':'C5S', + 'hyb':'' + }, + "P" : { + 'type':'PN', + 'hyb':'' + }, + "C4'" : { + 'type':'C4S', + 'hyb':'' + }, + "C2'" : { + 'type':'C2S', + 'hyb':'' + }, + "N1" : { + 'type':'N1C', + 'hyb':'' + }, + "H2'" : { + 'type':'H0', + 'hyb':'' + }, + "N3" : { + 'type':'N3C', + 'hyb':'' + }, + "N4" : { + 'type':'N4C', + 'hyb':'' + }, + "O2" : { + 'type':'O2C', + 'hyb':'' + }, + "H3'" : { + 'type':'H0', + 'hyb':'' + }, + "H4'" : { + 'type':'H0', + 'hyb':'' + }, + "H42" : { + 'type':'H', + 'hyb':'' + }, + "H5'" : { + 'type':'H0', + 'hyb':'' + }, + "'H5'" : { + 'type':'H0', + 'hyb':'' + }, + "O5'" : { + 'type':'O5S', + 'hyb':'' + }, + "H5" : { + 'type':'H0', + 'hyb':'' + }, + "O4'" : { + 'type':'O4S', + 'hyb':'' + }, + "H6" : { + 'type':'H0', + 'hyb':'' + }, + "O3'" : { + 'type':'O3S', + 'hyb':'' + }, + "H41" : { + 'type':'H', + 'hyb':'' + }, + "C2" : { + 'type':'C2C', + 'hyb':'' + }, + "H1'" : { + 'type':'H0', + 'hyb':'' + }, + "C6" : { + 'type':'C6C', + 'hyb':'' + }, + "C5" : { + 'type':'C5C', + 'hyb':'' + }, + "C4" : { + 'type':'C4C', + 'hyb':'' + }, + }, + 'HOH': { + "H2" : { + 'type':'HWAT', + 'hyb':'' + }, + "H1" : { + 'type':'HWAT', + 'hyb':'' + }, + "O" : { + 'type':'OWAT', + 'hyb':'' + }, + }, + 'SOL': { + "MW" : { + 'type':'MWAT', + 'hyb':'' + }, + "OW4" : { + 'type':'OWAT', + 'hyb':'' + }, + "OW" : { + 'type':'OWAT', + 'hyb':'' + }, + "MW1" : { + 'type':'MWAT', + 'hyb':'' + }, + "HW2" : { + 'type':'HWAT', + 'hyb':'' + }, + "HW3" : { + 'type':'HWAT', + 'hyb':'' + }, + "HW1" : { + 'type':'HWAT', + 'hyb':'' + }, + }, + 'NA': { + "NA" : { + 'type':'NA', + 'hyb':'' + }, + }, + 'MG': { + "MG" : { + 'type':'MG', + 'hyb':'' + }, + }, + 'CA': { + "CA" : { + 'type':'CAL', + 'hyb':'' + }, + }, + 'K': { + "K" : { + 'type':'K', + 'hyb':'' + }, + }, + 'ZN': { + "ZN" : { + 'type':'ZN', + 'hyb':'' + }, + }, + 'FE': { + "FE" : { + 'type':'FE', + 'hyb':'' + }, + }, + 'MN': { + "MN" : { + 'type':'MN', + 'hyb':'' + }, + }, + 'SO4': { + "S" : { + 'type':'SUL', + 'hyb':'' + }, + "O4" : { + 'type':'OSUL', + 'hyb':'' + }, + "O3" : { + 'type':'OSUL', + 'hyb':'' + }, + "O2" : { + 'type':'OSUL', + 'hyb':'' + }, + "O1" : { + 'type':'OSUL', + 'hyb':'' + }, + }, + 'CL-': { + "CL" : { + 'type':'CL', + 'hyb':'' + }, + }, } @@ -4159,729 +4159,729 @@ def pmx_data_file( filename ): ['CG', 'CB', 'CA', 'HA', 0, -1] , ['CG', 'CB', 'CA', 'N', 0, -1] , ), - 'ALA' : ( - ['N', 'CA', 'CB', 'HB1', 1, 1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'HB3', 1, -1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'HB3', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['C', 'CA', 'CB', 'HB3', 1, -1] , - ), - 'CYS' : ( - ['N', 'CA', 'CB', 'HB1', 1, -1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'SG', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'SG', 'HG', 1, 2] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'SG', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'SG', 'HG', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'SG', 'HG', 1, -1] , - ['C', 'CA', 'CB', 'SG', 1, -1] , - ), - 'ASP' : ( - ['N', 'CA', 'CB', 'HB1', 1, -1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'CG', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'CG', 'OD1', 1, 2] , - ['CA', 'CB', 'CG', 'OD2', 1, -1] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'CG', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'CG', 'OD1', 1, -1] , - ['HB1', 'CB', 'CG', 'OD2', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'CG', 'OD1', 1, -1] , - ['HB2', 'CB', 'CG', 'OD2', 1, -1] , - ['C', 'CA', 'CB', 'CG', 1, -1] , - ), - 'GLU' : ( - ['N', 'CA', 'CB', 'HB1', 1, -1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'CG', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'CG', 'HG1', 1, -1] , - ['CA', 'CB', 'CG', 'HG2', 1, -1] , - ['CA', 'CB', 'CG', 'CD', 1, 2] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'CG', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CG', 'CD', 'OE1', 1, 3] , - ['CB', 'CG', 'CD', 'OE2', 1, -1] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'CG', 'HG1', 1, -1] , - ['HB1', 'CB', 'CG', 'HG2', 1, -1] , - ['HB1', 'CB', 'CG', 'CD', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'CG', 'HG1', 1, -1] , - ['HB2', 'CB', 'CG', 'HG2', 1, -1] , - ['HB2', 'CB', 'CG', 'CD', 1, -1] , - ['C', 'CA', 'CB', 'CG', 1, -1] , - ['HG1', 'CG', 'CD', 'OE1', 1, -1] , - ['HG1', 'CG', 'CD', 'OE2', 1, -1] , - ['HG2', 'CG', 'CD', 'OE1', 1, -1] , - ['HG2', 'CG', 'CD', 'OE2', 1, -1] , - ), - 'PHE' : ( - ['N', 'CA', 'CB', 'HB1', 1, -1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'CG', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'CG', 'CD1', 1, 2] , - ['CA', 'CB', 'CG', 'CD2', 1, -1] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'CG', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CG', 'CD1', 'HD1', 0, -1] , - ['CB', 'CG', 'CD1', 'CE1', 0, 3] , - ['CB', 'CG', 'CD2', 'HD2', 0, -1] , - ['CB', 'CG', 'CD2', 'CE2', 0, -1] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'CG', 'CD1', 1, -1] , - ['HB1', 'CB', 'CG', 'CD2', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'CG', 'CD1', 1, -1] , - ['HB2', 'CB', 'CG', 'CD2', 1, -1] , - ['C', 'CA', 'CB', 'CG', 1, -1] , - ['CG', 'CD1', 'CE1', 'HE1', 0, -1] , - ['CG', 'CD1', 'CE1', 'CZ', 0, 4] , - ['CG', 'CD2', 'CE2', 'HE2', 0, -1] , - ['CG', 'CD2', 'CE2', 'CZ', 0, -1] , - ['CD1', 'CG', 'CD2', 'HD2', 0, -1] , - ['CD1', 'CG', 'CD2', 'CE2', 0, -1] , - ['CD1', 'CE1', 'CZ', 'CE2', 0, 5] , - ['CD1', 'CE1', 'CZ', 'HZ', 0, -1] , - ['CD2', 'CG', 'CD1', 'HD1', 0, -1] , - ['HD1', 'CD1', 'CE1', 'HE1', 0, -1] , - ['HD1', 'CD1', 'CE1', 'CZ', 0, -1] , - ['CD2', 'CG', 'CD1', 'CE1', 0, -1] , - ['CD2', 'CE2', 'CZ', 'CE1', 0, -1] , - ['CD2', 'CE2', 'CZ', 'HZ', 0, -1] , - ['HD2', 'CD2', 'CE2', 'HE2', 0, -1] , - ['HD2', 'CD2', 'CE2', 'CZ', 0, -1] , - ['CE1', 'CZ', 'CE2', 'HE2', 0, -1] , - ['CE2', 'CZ', 'CE1', 'HE1', 0, -1] , - ['HE1', 'CE1', 'CZ', 'HZ', 0, -1] , - ['HE2', 'CE2', 'CZ', 'HZ', 0, -1] , - ), - 'GLY' : ( - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA1', 1, -1] , - ['H', 'N', 'CA', 'HA2', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['HA1', 'CA', 'C', 'O', 1, -1] , - ['HA2', 'CA', 'C', 'O', 1, -1] , - ), - 'HIS' : ( - ['N', 'CA', 'CB', 'HB1', 1, -1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'CG', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'CG', 'ND1', 1, 2] , - ['CA', 'CB', 'CG', 'CD2', 1, -1] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'CG', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CG', 'ND1', 'CE1', 0, 3] , - ['CB', 'CG', 'CD2', 'HD2', 0, -1] , - ['CB', 'CG', 'CD2', 'NE2', 0, -1] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'CG', 'ND1', 1, -1] , - ['HB1', 'CB', 'CG', 'CD2', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'CG', 'ND1', 1, -1] , - ['HB2', 'CB', 'CG', 'CD2', 1, -1] , - ['C', 'CA', 'CB', 'CG', 1, -1] , - ['CG', 'ND1', 'CE1', 'HE1', 0, 4] , - ['CG', 'CD2', 'NE2', 'HE2', 0, -1] , - ['ND1', 'CG', 'CD2', 'HD2', 0, -1] , - ['ND1', 'CG', 'CD2', 'NE2', 0, -1] , - ['CD2', 'CG', 'ND1', 'CE1', 0, -1] , - ['HD2', 'CD2', 'NE2', 'HE2', 0, -1] , - ), - 'ILE' : ( - ['N', 'CA', 'CB', 'HB', 1, -1] , - ['N', 'CA', 'CB', 'CG1', 1, 1] , - ['N', 'CA', 'CB', 'CG2', 1, -1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'CG1', 'HG11', 1, -1] , - ['CA', 'CB', 'CG1', 'HG12', 1, -1] , - ['CA', 'CB', 'CG1', 'CD1', 1, 2] , - ['CA', 'CB', 'CG2', 'HG21', 1, -1] , - ['CA', 'CB', 'CG2', 'HG22', 1, -1] , - ['CA', 'CB', 'CG2', 'HG23', 1, -1] , - ['HA', 'CA', 'CB', 'HB', 1, -1] , - ['HA', 'CA', 'CB', 'CG1', 1, -1] , - ['HA', 'CA', 'CB', 'CG2', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CG1', 'CD1', 'HD11', 1, 3] , - ['CB', 'CG1', 'CD1', 'HD12', 1, -1] , - ['CB', 'CG1', 'CD1', 'HD13', 1, -1] , - ['C', 'CA', 'CB', 'HB', 1, -1] , - ['HB', 'CB', 'CG1', 'HG11', 1, -1] , - ['HB', 'CB', 'CG1', 'HG12', 1, -1] , - ['HB', 'CB', 'CG1', 'CD1', 1, -1] , - ['HB', 'CB', 'CG2', 'HG21', 1, -1] , - ['HB', 'CB', 'CG2', 'HG22', 1, -1] , - ['HB', 'CB', 'CG2', 'HG23', 1, -1] , - ['C', 'CA', 'CB', 'CG1', 1, -1] , - ['CG1', 'CB', 'CG2', 'HG21', 1, -1] , - ['CG1', 'CB', 'CG2', 'HG22', 1, -1] , - ['CG1', 'CB', 'CG2', 'HG23', 1, -1] , - ['CG2', 'CB', 'CG1', 'HG11', 1, -1] , - ['HG11', 'CG1', 'CD1', 'HD11', 1, -1] , - ['HG11', 'CG1', 'CD1', 'HD12', 1, -1] , - ['HG11', 'CG1', 'CD1', 'HD13', 1, -1] , - ['CG2', 'CB', 'CG1', 'HG12', 1, -1] , - ['HG12', 'CG1', 'CD1', 'HD11', 1, -1] , - ['HG12', 'CG1', 'CD1', 'HD12', 1, -1] , - ['HG12', 'CG1', 'CD1', 'HD13', 1, -1] , - ['C', 'CA', 'CB', 'CG2', 1, -1] , - ['CG2', 'CB', 'CG1', 'CD1', 1, -1] , - ), - 'LYS' : ( - ['N', 'CA', 'CB', 'HB1', 1, -1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'CG', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'CG', 'HG1', 1, -1] , - ['CA', 'CB', 'CG', 'HG2', 1, -1] , - ['CA', 'CB', 'CG', 'CD', 1, 2] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'CG', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CG', 'CD', 'HD1', 1, -1] , - ['CB', 'CG', 'CD', 'HD2', 1, -1] , - ['CB', 'CG', 'CD', 'CE', 1, 3] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'CG', 'HG1', 1, -1] , - ['HB1', 'CB', 'CG', 'HG2', 1, -1] , - ['HB1', 'CB', 'CG', 'CD', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'CG', 'HG1', 1, -1] , - ['HB2', 'CB', 'CG', 'HG2', 1, -1] , - ['HB2', 'CB', 'CG', 'CD', 1, -1] , - ['C', 'CA', 'CB', 'CG', 1, -1] , - ['CG', 'CD', 'CE', 'HE1', 1, -1] , - ['CG', 'CD', 'CE', 'HE2', 1, -1] , - ['CG', 'CD', 'CE', 'NZ', 1, 4] , - ['HG1', 'CG', 'CD', 'HD1', 1, -1] , - ['HG1', 'CG', 'CD', 'HD2', 1, -1] , - ['HG1', 'CG', 'CD', 'CE', 1, -1] , - ['HG2', 'CG', 'CD', 'HD1', 1, -1] , - ['HG2', 'CG', 'CD', 'HD2', 1, -1] , - ['HG2', 'CG', 'CD', 'CE', 1, -1] , - ['CD', 'CE', 'NZ', 'HZ1', 1, 5] , - ['CD', 'CE', 'NZ', 'HZ2', 1, -1] , - ['CD', 'CE', 'NZ', 'HZ3', 1, -1] , - ['HD1', 'CD', 'CE', 'HE1', 1, -1] , - ['HD1', 'CD', 'CE', 'HE2', 1, -1] , - ['HD1', 'CD', 'CE', 'NZ', 1, -1] , - ['HD2', 'CD', 'CE', 'HE1', 1, -1] , - ['HD2', 'CD', 'CE', 'HE2', 1, -1] , - ['HD2', 'CD', 'CE', 'NZ', 1, -1] , - ['HE1', 'CE', 'NZ', 'HZ1', 1, -1] , - ['HE1', 'CE', 'NZ', 'HZ2', 1, -1] , - ['HE1', 'CE', 'NZ', 'HZ3', 1, -1] , - ['HE2', 'CE', 'NZ', 'HZ1', 1, -1] , - ['HE2', 'CE', 'NZ', 'HZ2', 1, -1] , - ['HE2', 'CE', 'NZ', 'HZ3', 1, -1] , - ), - 'LEU' : ( - ['N', 'CA', 'CB', 'HB1', 1, -1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'CG', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'CG', 'HG', 1, -1] , - ['CA', 'CB', 'CG', 'CD1', 1, 2] , - ['CA', 'CB', 'CG', 'CD2', 1, -1] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'CG', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CG', 'CD1', 'HD11', 1, 3] , - ['CB', 'CG', 'CD1', 'HD12', 1, -1] , - ['CB', 'CG', 'CD1', 'HD13', 1, -1] , - ['CB', 'CG', 'CD2', 'HD21', 1, -1] , - ['CB', 'CG', 'CD2', 'HD22', 1, -1] , - ['CB', 'CG', 'CD2', 'HD23', 1, -1] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'CG', 'HG', 1, -1] , - ['HB1', 'CB', 'CG', 'CD1', 1, -1] , - ['HB1', 'CB', 'CG', 'CD2', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'CG', 'HG', 1, -1] , - ['HB2', 'CB', 'CG', 'CD1', 1, -1] , - ['HB2', 'CB', 'CG', 'CD2', 1, -1] , - ['C', 'CA', 'CB', 'CG', 1, -1] , - ['HG', 'CG', 'CD1', 'HD11', 1, -1] , - ['HG', 'CG', 'CD1', 'HD12', 1, -1] , - ['HG', 'CG', 'CD1', 'HD13', 1, -1] , - ['HG', 'CG', 'CD2', 'HD21', 1, -1] , - ['HG', 'CG', 'CD2', 'HD22', 1, -1] , - ['HG', 'CG', 'CD2', 'HD23', 1, -1] , - ['CD1', 'CG', 'CD2', 'HD21', 1, -1] , - ['CD1', 'CG', 'CD2', 'HD22', 1, -1] , - ['CD1', 'CG', 'CD2', 'HD23', 1, -1] , - ['CD2', 'CG', 'CD1', 'HD11', 1, -1] , - ['CD2', 'CG', 'CD1', 'HD12', 1, -1] , - ['CD2', 'CG', 'CD1', 'HD13', 1, -1] , - ), - 'MET' : ( - ['N', 'CA', 'CB', 'HB1', 1, -1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'CG', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'CG', 'HG1', 1, -1] , - ['CA', 'CB', 'CG', 'HG2', 1, -1] , - ['CA', 'CB', 'CG', 'SD', 1, 2] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'CG', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CG', 'SD', 'CE', 1, 3] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'CG', 'HG1', 1, -1] , - ['HB1', 'CB', 'CG', 'HG2', 1, -1] , - ['HB1', 'CB', 'CG', 'SD', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'CG', 'HG1', 1, -1] , - ['HB2', 'CB', 'CG', 'HG2', 1, -1] , - ['HB2', 'CB', 'CG', 'SD', 1, -1] , - ['C', 'CA', 'CB', 'CG', 1, -1] , - ['CG', 'SD', 'CE', 'HE1', 1, 4] , - ['CG', 'SD', 'CE', 'HE2', 1, -1] , - ['CG', 'SD', 'CE', 'HE3', 1, -1] , - ['HG1', 'CG', 'SD', 'CE', 1, -1] , - ['HG2', 'CG', 'SD', 'CE', 1, -1] , - ), - 'ASN' : ( - ['N', 'CA', 'CB', 'HB1', 1, -1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'CG', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'CG', 'OD1', 1, 2] , - ['CA', 'CB', 'CG', 'ND2', 1, -1] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'CG', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CG', 'ND2', 'HD21', 0, -1] , - ['CB', 'CG', 'ND2', 'HD22', 0, -1] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'CG', 'OD1', 1, -1] , - ['HB1', 'CB', 'CG', 'ND2', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'CG', 'OD1', 1, -1] , - ['HB2', 'CB', 'CG', 'ND2', 1, -1] , - ['C', 'CA', 'CB', 'CG', 1, -1] , - ['OD1', 'CG', 'ND2', 'HD21', 0, -1] , - ['OD1', 'CG', 'ND2', 'HD22', 0, -1] , - ), - 'GLN' : ( - ['N', 'CA', 'CB', 'HB1', 1, -1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'CG', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'CG', 'HG1', 1, -1] , - ['CA', 'CB', 'CG', 'HG2', 1, -1] , - ['CA', 'CB', 'CG', 'CD', 1, 2] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'CG', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CG', 'CD', 'OE1', 1, 3] , - ['CB', 'CG', 'CD', 'NE2', 1, -1] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'CG', 'HG1', 1, -1] , - ['HB1', 'CB', 'CG', 'HG2', 1, -1] , - ['HB1', 'CB', 'CG', 'CD', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'CG', 'HG1', 1, -1] , - ['HB2', 'CB', 'CG', 'HG2', 1, -1] , - ['HB2', 'CB', 'CG', 'CD', 1, -1] , - ['C', 'CA', 'CB', 'CG', 1, -1] , - ['CG', 'CD', 'NE2', 'HE21', 0, -1] , - ['CG', 'CD', 'NE2', 'HE22', 0, -1] , - ['HG1', 'CG', 'CD', 'OE1', 1, -1] , - ['HG1', 'CG', 'CD', 'NE2', 1, -1] , - ['HG2', 'CG', 'CD', 'OE1', 1, -1] , - ['HG2', 'CG', 'CD', 'NE2', 1, -1] , - ['OE1', 'CD', 'NE2', 'HE21', 0, -1] , - ['OE1', 'CD', 'NE2', 'HE22', 0, -1] , - ), - 'ARG' : ( - ['N', 'CA', 'CB', 'HB1', 1, -1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'CG', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'CG', 'HG1', 1, -1] , - ['CA', 'CB', 'CG', 'HG2', 1, -1] , - ['CA', 'CB', 'CG', 'CD', 1, 2] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'CG', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CG', 'CD', 'HD1', 1, -1] , - ['CB', 'CG', 'CD', 'HD2', 1, -1] , - ['CB', 'CG', 'CD', 'NE', 1, 3] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'CG', 'HG1', 1, -1] , - ['HB1', 'CB', 'CG', 'HG2', 1, -1] , - ['HB1', 'CB', 'CG', 'CD', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'CG', 'HG1', 1, -1] , - ['HB2', 'CB', 'CG', 'HG2', 1, -1] , - ['HB2', 'CB', 'CG', 'CD', 1, -1] , - ['C', 'CA', 'CB', 'CG', 1, -1] , - ['CG', 'CD', 'NE', 'HE', 1, -1] , - ['CG', 'CD', 'NE', 'CZ', 1, 4] , - ['HG1', 'CG', 'CD', 'HD1', 1, -1] , - ['HG1', 'CG', 'CD', 'HD2', 1, -1] , - ['HG1', 'CG', 'CD', 'NE', 1, -1] , - ['HG2', 'CG', 'CD', 'HD1', 1, -1] , - ['HG2', 'CG', 'CD', 'HD2', 1, -1] , - ['HG2', 'CG', 'CD', 'NE', 1, -1] , - ['CD', 'NE', 'CZ', 'NH1', 0, 5] , - ['CD', 'NE', 'CZ', 'NH2', 0, -1] , - ['HD1', 'CD', 'NE', 'HE', 1, -1] , - ['HD1', 'CD', 'NE', 'CZ', 1, -1] , - ['HD2', 'CD', 'NE', 'HE', 1, -1] , - ['HD2', 'CD', 'NE', 'CZ', 1, -1] , - ['NE', 'CZ', 'NH1', 'HH11', 0, 6] , - ['NE', 'CZ', 'NH1', 'HH12', 0, -1] , - ['NE', 'CZ', 'NH2', 'HH21', 0, -1] , - ['NE', 'CZ', 'NH2', 'HH22', 0, -1] , - ['HE', 'NE', 'CZ', 'NH1', 0, -1] , - ['HE', 'NE', 'CZ', 'NH2', 0, -1] , - ['NH1', 'CZ', 'NH2', 'HH21', 0, -1] , - ['NH1', 'CZ', 'NH2', 'HH22', 0, -1] , - ['NH2', 'CZ', 'NH1', 'HH11', 0, -1] , - ['NH2', 'CZ', 'NH1', 'HH12', 0, -1] , - ), - 'SER' : ( - ['N', 'CA', 'CB', 'HB1', 1, -1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'OG', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'OG', 'HG', 1, 2] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'OG', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'OG', 'HG', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'OG', 'HG', 1, -1] , - ['C', 'CA', 'CB', 'OG', 1, -1] , - ), + 'ALA' : ( + ['N', 'CA', 'CB', 'HB1', 1, 1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'HB3', 1, -1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'HB3', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['C', 'CA', 'CB', 'HB3', 1, -1] , + ), + 'CYS' : ( + ['N', 'CA', 'CB', 'HB1', 1, -1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'SG', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'SG', 'HG', 1, 2] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'SG', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'SG', 'HG', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'SG', 'HG', 1, -1] , + ['C', 'CA', 'CB', 'SG', 1, -1] , + ), + 'ASP' : ( + ['N', 'CA', 'CB', 'HB1', 1, -1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'CG', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'CG', 'OD1', 1, 2] , + ['CA', 'CB', 'CG', 'OD2', 1, -1] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'CG', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'CG', 'OD1', 1, -1] , + ['HB1', 'CB', 'CG', 'OD2', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'CG', 'OD1', 1, -1] , + ['HB2', 'CB', 'CG', 'OD2', 1, -1] , + ['C', 'CA', 'CB', 'CG', 1, -1] , + ), + 'GLU' : ( + ['N', 'CA', 'CB', 'HB1', 1, -1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'CG', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'CG', 'HG1', 1, -1] , + ['CA', 'CB', 'CG', 'HG2', 1, -1] , + ['CA', 'CB', 'CG', 'CD', 1, 2] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'CG', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CG', 'CD', 'OE1', 1, 3] , + ['CB', 'CG', 'CD', 'OE2', 1, -1] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'CG', 'HG1', 1, -1] , + ['HB1', 'CB', 'CG', 'HG2', 1, -1] , + ['HB1', 'CB', 'CG', 'CD', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'CG', 'HG1', 1, -1] , + ['HB2', 'CB', 'CG', 'HG2', 1, -1] , + ['HB2', 'CB', 'CG', 'CD', 1, -1] , + ['C', 'CA', 'CB', 'CG', 1, -1] , + ['HG1', 'CG', 'CD', 'OE1', 1, -1] , + ['HG1', 'CG', 'CD', 'OE2', 1, -1] , + ['HG2', 'CG', 'CD', 'OE1', 1, -1] , + ['HG2', 'CG', 'CD', 'OE2', 1, -1] , + ), + 'PHE' : ( + ['N', 'CA', 'CB', 'HB1', 1, -1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'CG', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'CG', 'CD1', 1, 2] , + ['CA', 'CB', 'CG', 'CD2', 1, -1] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'CG', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CG', 'CD1', 'HD1', 0, -1] , + ['CB', 'CG', 'CD1', 'CE1', 0, 3] , + ['CB', 'CG', 'CD2', 'HD2', 0, -1] , + ['CB', 'CG', 'CD2', 'CE2', 0, -1] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'CG', 'CD1', 1, -1] , + ['HB1', 'CB', 'CG', 'CD2', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'CG', 'CD1', 1, -1] , + ['HB2', 'CB', 'CG', 'CD2', 1, -1] , + ['C', 'CA', 'CB', 'CG', 1, -1] , + ['CG', 'CD1', 'CE1', 'HE1', 0, -1] , + ['CG', 'CD1', 'CE1', 'CZ', 0, 4] , + ['CG', 'CD2', 'CE2', 'HE2', 0, -1] , + ['CG', 'CD2', 'CE2', 'CZ', 0, -1] , + ['CD1', 'CG', 'CD2', 'HD2', 0, -1] , + ['CD1', 'CG', 'CD2', 'CE2', 0, -1] , + ['CD1', 'CE1', 'CZ', 'CE2', 0, 5] , + ['CD1', 'CE1', 'CZ', 'HZ', 0, -1] , + ['CD2', 'CG', 'CD1', 'HD1', 0, -1] , + ['HD1', 'CD1', 'CE1', 'HE1', 0, -1] , + ['HD1', 'CD1', 'CE1', 'CZ', 0, -1] , + ['CD2', 'CG', 'CD1', 'CE1', 0, -1] , + ['CD2', 'CE2', 'CZ', 'CE1', 0, -1] , + ['CD2', 'CE2', 'CZ', 'HZ', 0, -1] , + ['HD2', 'CD2', 'CE2', 'HE2', 0, -1] , + ['HD2', 'CD2', 'CE2', 'CZ', 0, -1] , + ['CE1', 'CZ', 'CE2', 'HE2', 0, -1] , + ['CE2', 'CZ', 'CE1', 'HE1', 0, -1] , + ['HE1', 'CE1', 'CZ', 'HZ', 0, -1] , + ['HE2', 'CE2', 'CZ', 'HZ', 0, -1] , + ), + 'GLY' : ( + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA1', 1, -1] , + ['H', 'N', 'CA', 'HA2', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['HA1', 'CA', 'C', 'O', 1, -1] , + ['HA2', 'CA', 'C', 'O', 1, -1] , + ), + 'HIS' : ( + ['N', 'CA', 'CB', 'HB1', 1, -1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'CG', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'CG', 'ND1', 1, 2] , + ['CA', 'CB', 'CG', 'CD2', 1, -1] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'CG', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CG', 'ND1', 'CE1', 0, 3] , + ['CB', 'CG', 'CD2', 'HD2', 0, -1] , + ['CB', 'CG', 'CD2', 'NE2', 0, -1] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'CG', 'ND1', 1, -1] , + ['HB1', 'CB', 'CG', 'CD2', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'CG', 'ND1', 1, -1] , + ['HB2', 'CB', 'CG', 'CD2', 1, -1] , + ['C', 'CA', 'CB', 'CG', 1, -1] , + ['CG', 'ND1', 'CE1', 'HE1', 0, 4] , + ['CG', 'CD2', 'NE2', 'HE2', 0, -1] , + ['ND1', 'CG', 'CD2', 'HD2', 0, -1] , + ['ND1', 'CG', 'CD2', 'NE2', 0, -1] , + ['CD2', 'CG', 'ND1', 'CE1', 0, -1] , + ['HD2', 'CD2', 'NE2', 'HE2', 0, -1] , + ), + 'ILE' : ( + ['N', 'CA', 'CB', 'HB', 1, -1] , + ['N', 'CA', 'CB', 'CG1', 1, 1] , + ['N', 'CA', 'CB', 'CG2', 1, -1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'CG1', 'HG11', 1, -1] , + ['CA', 'CB', 'CG1', 'HG12', 1, -1] , + ['CA', 'CB', 'CG1', 'CD1', 1, 2] , + ['CA', 'CB', 'CG2', 'HG21', 1, -1] , + ['CA', 'CB', 'CG2', 'HG22', 1, -1] , + ['CA', 'CB', 'CG2', 'HG23', 1, -1] , + ['HA', 'CA', 'CB', 'HB', 1, -1] , + ['HA', 'CA', 'CB', 'CG1', 1, -1] , + ['HA', 'CA', 'CB', 'CG2', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CG1', 'CD1', 'HD11', 1, 3] , + ['CB', 'CG1', 'CD1', 'HD12', 1, -1] , + ['CB', 'CG1', 'CD1', 'HD13', 1, -1] , + ['C', 'CA', 'CB', 'HB', 1, -1] , + ['HB', 'CB', 'CG1', 'HG11', 1, -1] , + ['HB', 'CB', 'CG1', 'HG12', 1, -1] , + ['HB', 'CB', 'CG1', 'CD1', 1, -1] , + ['HB', 'CB', 'CG2', 'HG21', 1, -1] , + ['HB', 'CB', 'CG2', 'HG22', 1, -1] , + ['HB', 'CB', 'CG2', 'HG23', 1, -1] , + ['C', 'CA', 'CB', 'CG1', 1, -1] , + ['CG1', 'CB', 'CG2', 'HG21', 1, -1] , + ['CG1', 'CB', 'CG2', 'HG22', 1, -1] , + ['CG1', 'CB', 'CG2', 'HG23', 1, -1] , + ['CG2', 'CB', 'CG1', 'HG11', 1, -1] , + ['HG11', 'CG1', 'CD1', 'HD11', 1, -1] , + ['HG11', 'CG1', 'CD1', 'HD12', 1, -1] , + ['HG11', 'CG1', 'CD1', 'HD13', 1, -1] , + ['CG2', 'CB', 'CG1', 'HG12', 1, -1] , + ['HG12', 'CG1', 'CD1', 'HD11', 1, -1] , + ['HG12', 'CG1', 'CD1', 'HD12', 1, -1] , + ['HG12', 'CG1', 'CD1', 'HD13', 1, -1] , + ['C', 'CA', 'CB', 'CG2', 1, -1] , + ['CG2', 'CB', 'CG1', 'CD1', 1, -1] , + ), + 'LYS' : ( + ['N', 'CA', 'CB', 'HB1', 1, -1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'CG', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'CG', 'HG1', 1, -1] , + ['CA', 'CB', 'CG', 'HG2', 1, -1] , + ['CA', 'CB', 'CG', 'CD', 1, 2] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'CG', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CG', 'CD', 'HD1', 1, -1] , + ['CB', 'CG', 'CD', 'HD2', 1, -1] , + ['CB', 'CG', 'CD', 'CE', 1, 3] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'CG', 'HG1', 1, -1] , + ['HB1', 'CB', 'CG', 'HG2', 1, -1] , + ['HB1', 'CB', 'CG', 'CD', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'CG', 'HG1', 1, -1] , + ['HB2', 'CB', 'CG', 'HG2', 1, -1] , + ['HB2', 'CB', 'CG', 'CD', 1, -1] , + ['C', 'CA', 'CB', 'CG', 1, -1] , + ['CG', 'CD', 'CE', 'HE1', 1, -1] , + ['CG', 'CD', 'CE', 'HE2', 1, -1] , + ['CG', 'CD', 'CE', 'NZ', 1, 4] , + ['HG1', 'CG', 'CD', 'HD1', 1, -1] , + ['HG1', 'CG', 'CD', 'HD2', 1, -1] , + ['HG1', 'CG', 'CD', 'CE', 1, -1] , + ['HG2', 'CG', 'CD', 'HD1', 1, -1] , + ['HG2', 'CG', 'CD', 'HD2', 1, -1] , + ['HG2', 'CG', 'CD', 'CE', 1, -1] , + ['CD', 'CE', 'NZ', 'HZ1', 1, 5] , + ['CD', 'CE', 'NZ', 'HZ2', 1, -1] , + ['CD', 'CE', 'NZ', 'HZ3', 1, -1] , + ['HD1', 'CD', 'CE', 'HE1', 1, -1] , + ['HD1', 'CD', 'CE', 'HE2', 1, -1] , + ['HD1', 'CD', 'CE', 'NZ', 1, -1] , + ['HD2', 'CD', 'CE', 'HE1', 1, -1] , + ['HD2', 'CD', 'CE', 'HE2', 1, -1] , + ['HD2', 'CD', 'CE', 'NZ', 1, -1] , + ['HE1', 'CE', 'NZ', 'HZ1', 1, -1] , + ['HE1', 'CE', 'NZ', 'HZ2', 1, -1] , + ['HE1', 'CE', 'NZ', 'HZ3', 1, -1] , + ['HE2', 'CE', 'NZ', 'HZ1', 1, -1] , + ['HE2', 'CE', 'NZ', 'HZ2', 1, -1] , + ['HE2', 'CE', 'NZ', 'HZ3', 1, -1] , + ), + 'LEU' : ( + ['N', 'CA', 'CB', 'HB1', 1, -1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'CG', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'CG', 'HG', 1, -1] , + ['CA', 'CB', 'CG', 'CD1', 1, 2] , + ['CA', 'CB', 'CG', 'CD2', 1, -1] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'CG', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CG', 'CD1', 'HD11', 1, 3] , + ['CB', 'CG', 'CD1', 'HD12', 1, -1] , + ['CB', 'CG', 'CD1', 'HD13', 1, -1] , + ['CB', 'CG', 'CD2', 'HD21', 1, -1] , + ['CB', 'CG', 'CD2', 'HD22', 1, -1] , + ['CB', 'CG', 'CD2', 'HD23', 1, -1] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'CG', 'HG', 1, -1] , + ['HB1', 'CB', 'CG', 'CD1', 1, -1] , + ['HB1', 'CB', 'CG', 'CD2', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'CG', 'HG', 1, -1] , + ['HB2', 'CB', 'CG', 'CD1', 1, -1] , + ['HB2', 'CB', 'CG', 'CD2', 1, -1] , + ['C', 'CA', 'CB', 'CG', 1, -1] , + ['HG', 'CG', 'CD1', 'HD11', 1, -1] , + ['HG', 'CG', 'CD1', 'HD12', 1, -1] , + ['HG', 'CG', 'CD1', 'HD13', 1, -1] , + ['HG', 'CG', 'CD2', 'HD21', 1, -1] , + ['HG', 'CG', 'CD2', 'HD22', 1, -1] , + ['HG', 'CG', 'CD2', 'HD23', 1, -1] , + ['CD1', 'CG', 'CD2', 'HD21', 1, -1] , + ['CD1', 'CG', 'CD2', 'HD22', 1, -1] , + ['CD1', 'CG', 'CD2', 'HD23', 1, -1] , + ['CD2', 'CG', 'CD1', 'HD11', 1, -1] , + ['CD2', 'CG', 'CD1', 'HD12', 1, -1] , + ['CD2', 'CG', 'CD1', 'HD13', 1, -1] , + ), + 'MET' : ( + ['N', 'CA', 'CB', 'HB1', 1, -1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'CG', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'CG', 'HG1', 1, -1] , + ['CA', 'CB', 'CG', 'HG2', 1, -1] , + ['CA', 'CB', 'CG', 'SD', 1, 2] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'CG', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CG', 'SD', 'CE', 1, 3] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'CG', 'HG1', 1, -1] , + ['HB1', 'CB', 'CG', 'HG2', 1, -1] , + ['HB1', 'CB', 'CG', 'SD', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'CG', 'HG1', 1, -1] , + ['HB2', 'CB', 'CG', 'HG2', 1, -1] , + ['HB2', 'CB', 'CG', 'SD', 1, -1] , + ['C', 'CA', 'CB', 'CG', 1, -1] , + ['CG', 'SD', 'CE', 'HE1', 1, 4] , + ['CG', 'SD', 'CE', 'HE2', 1, -1] , + ['CG', 'SD', 'CE', 'HE3', 1, -1] , + ['HG1', 'CG', 'SD', 'CE', 1, -1] , + ['HG2', 'CG', 'SD', 'CE', 1, -1] , + ), + 'ASN' : ( + ['N', 'CA', 'CB', 'HB1', 1, -1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'CG', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'CG', 'OD1', 1, 2] , + ['CA', 'CB', 'CG', 'ND2', 1, -1] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'CG', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CG', 'ND2', 'HD21', 0, -1] , + ['CB', 'CG', 'ND2', 'HD22', 0, -1] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'CG', 'OD1', 1, -1] , + ['HB1', 'CB', 'CG', 'ND2', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'CG', 'OD1', 1, -1] , + ['HB2', 'CB', 'CG', 'ND2', 1, -1] , + ['C', 'CA', 'CB', 'CG', 1, -1] , + ['OD1', 'CG', 'ND2', 'HD21', 0, -1] , + ['OD1', 'CG', 'ND2', 'HD22', 0, -1] , + ), + 'GLN' : ( + ['N', 'CA', 'CB', 'HB1', 1, -1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'CG', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'CG', 'HG1', 1, -1] , + ['CA', 'CB', 'CG', 'HG2', 1, -1] , + ['CA', 'CB', 'CG', 'CD', 1, 2] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'CG', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CG', 'CD', 'OE1', 1, 3] , + ['CB', 'CG', 'CD', 'NE2', 1, -1] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'CG', 'HG1', 1, -1] , + ['HB1', 'CB', 'CG', 'HG2', 1, -1] , + ['HB1', 'CB', 'CG', 'CD', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'CG', 'HG1', 1, -1] , + ['HB2', 'CB', 'CG', 'HG2', 1, -1] , + ['HB2', 'CB', 'CG', 'CD', 1, -1] , + ['C', 'CA', 'CB', 'CG', 1, -1] , + ['CG', 'CD', 'NE2', 'HE21', 0, -1] , + ['CG', 'CD', 'NE2', 'HE22', 0, -1] , + ['HG1', 'CG', 'CD', 'OE1', 1, -1] , + ['HG1', 'CG', 'CD', 'NE2', 1, -1] , + ['HG2', 'CG', 'CD', 'OE1', 1, -1] , + ['HG2', 'CG', 'CD', 'NE2', 1, -1] , + ['OE1', 'CD', 'NE2', 'HE21', 0, -1] , + ['OE1', 'CD', 'NE2', 'HE22', 0, -1] , + ), + 'ARG' : ( + ['N', 'CA', 'CB', 'HB1', 1, -1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'CG', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'CG', 'HG1', 1, -1] , + ['CA', 'CB', 'CG', 'HG2', 1, -1] , + ['CA', 'CB', 'CG', 'CD', 1, 2] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'CG', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CG', 'CD', 'HD1', 1, -1] , + ['CB', 'CG', 'CD', 'HD2', 1, -1] , + ['CB', 'CG', 'CD', 'NE', 1, 3] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'CG', 'HG1', 1, -1] , + ['HB1', 'CB', 'CG', 'HG2', 1, -1] , + ['HB1', 'CB', 'CG', 'CD', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'CG', 'HG1', 1, -1] , + ['HB2', 'CB', 'CG', 'HG2', 1, -1] , + ['HB2', 'CB', 'CG', 'CD', 1, -1] , + ['C', 'CA', 'CB', 'CG', 1, -1] , + ['CG', 'CD', 'NE', 'HE', 1, -1] , + ['CG', 'CD', 'NE', 'CZ', 1, 4] , + ['HG1', 'CG', 'CD', 'HD1', 1, -1] , + ['HG1', 'CG', 'CD', 'HD2', 1, -1] , + ['HG1', 'CG', 'CD', 'NE', 1, -1] , + ['HG2', 'CG', 'CD', 'HD1', 1, -1] , + ['HG2', 'CG', 'CD', 'HD2', 1, -1] , + ['HG2', 'CG', 'CD', 'NE', 1, -1] , + ['CD', 'NE', 'CZ', 'NH1', 0, 5] , + ['CD', 'NE', 'CZ', 'NH2', 0, -1] , + ['HD1', 'CD', 'NE', 'HE', 1, -1] , + ['HD1', 'CD', 'NE', 'CZ', 1, -1] , + ['HD2', 'CD', 'NE', 'HE', 1, -1] , + ['HD2', 'CD', 'NE', 'CZ', 1, -1] , + ['NE', 'CZ', 'NH1', 'HH11', 0, 6] , + ['NE', 'CZ', 'NH1', 'HH12', 0, -1] , + ['NE', 'CZ', 'NH2', 'HH21', 0, -1] , + ['NE', 'CZ', 'NH2', 'HH22', 0, -1] , + ['HE', 'NE', 'CZ', 'NH1', 0, -1] , + ['HE', 'NE', 'CZ', 'NH2', 0, -1] , + ['NH1', 'CZ', 'NH2', 'HH21', 0, -1] , + ['NH1', 'CZ', 'NH2', 'HH22', 0, -1] , + ['NH2', 'CZ', 'NH1', 'HH11', 0, -1] , + ['NH2', 'CZ', 'NH1', 'HH12', 0, -1] , + ), + 'SER' : ( + ['N', 'CA', 'CB', 'HB1', 1, -1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'OG', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'OG', 'HG', 1, 2] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'OG', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'OG', 'HG', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'OG', 'HG', 1, -1] , + ['C', 'CA', 'CB', 'OG', 1, -1] , + ), # phosphoserine in charmm36 - 'SP1' : ( - ['N', 'CA', 'CB', 'HB1', 1, -1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'OG', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'OG', 'PD', 1, 2] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'OG', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'OG', 'PD', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'OG', 'PD', 1, -1] , - ['C', 'CA', 'CB', 'OG', 1, -1] , - ['CB', 'OG', 'PD', 'OE1', 1, 3] , - ['CB', 'OG', 'PD', 'OE2', 1, -1] , - ['CB', 'OG', 'PD', 'OE', 1, -1] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'OG', 'PD', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'OG', 'PD', 1, -1] , - ['C', 'CA', 'CB', 'CG', 1, -1] , - ['OG', 'PD', 'OE', 'HE', 1, 4] , - ['O1E', 'PD', 'OE', 'HE', 1, -1] , - ['O2E', 'PD', 'OE', 'HE', 1, -1] , - ), + 'SP1' : ( + ['N', 'CA', 'CB', 'HB1', 1, -1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'OG', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'OG', 'PD', 1, 2] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'OG', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'OG', 'PD', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'OG', 'PD', 1, -1] , + ['C', 'CA', 'CB', 'OG', 1, -1] , + ['CB', 'OG', 'PD', 'OE1', 1, 3] , + ['CB', 'OG', 'PD', 'OE2', 1, -1] , + ['CB', 'OG', 'PD', 'OE', 1, -1] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'OG', 'PD', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'OG', 'PD', 1, -1] , + ['C', 'CA', 'CB', 'CG', 1, -1] , + ['OG', 'PD', 'OE', 'HE', 1, 4] , + ['O1E', 'PD', 'OE', 'HE', 1, -1] , + ['O2E', 'PD', 'OE', 'HE', 1, -1] , + ), # phosphoserine in charmm36 - 'SP2' : ( - ['N', 'CA', 'CB', 'HB1', 1, -1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'OG', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'OG', 'PD', 1, 2] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'OG', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'OG', 'PD', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'OG', 'PD', 1, -1] , - ['C', 'CA', 'CB', 'OG', 1, -1] , - ['CB', 'OG', 'PD', 'OE1', 1, 3] , - ['CB', 'OG', 'PD', 'OE2', 1, -1] , - ['CB', 'OG', 'PD', 'OE', 1, -1] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'OG', 'PD', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'OG', 'PD', 1, -1] , - ['C', 'CA', 'CB', 'CG', 1, -1] , - ), - 'SEP' : ( - ['N', 'CA', 'CB', 'HB1', 1, -1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'OG', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'OG', 'P', 1, 2] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'OG', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'OG', 'P', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'OG', 'P', 1, -1] , - ['C', 'CA', 'CB', 'OG', 1, -1] , - ['CB', 'OG', 'P', 'O1P', 1, 3] , - ['CB', 'OG', 'P', 'O2P', 1, -1] , - ['CB', 'OG', 'P', 'O3P', 1, -1] , - ), - 'THR' : ( - ['N', 'CA', 'CB', 'HB', 1, -1] , - ['N', 'CA', 'CB', 'OG1', 1, 1] , - ['N', 'CA', 'CB', 'CG2', 1, -1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'OG1', 'HG1', 1, 2] , - ['CA', 'CB', 'CG2', 'HG21', 1, -1] , - ['CA', 'CB', 'CG2', 'HG22', 1, -1] , - ['CA', 'CB', 'CG2', 'HG23', 1, -1] , - ['HA', 'CA', 'CB', 'HB', 1, -1] , - ['HA', 'CA', 'CB', 'OG1', 1, -1] , - ['HA', 'CA', 'CB', 'CG2', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['C', 'CA', 'CB', 'HB', 1, -1] , - ['HB', 'CB', 'OG1', 'HG1', 1, -1] , - ['HB', 'CB', 'CG2', 'HG21', 1, -1] , - ['HB', 'CB', 'CG2', 'HG22', 1, -1] , - ['HB', 'CB', 'CG2', 'HG23', 1, -1] , - ['C', 'CA', 'CB', 'OG1', 1, -1] , - ['OG1', 'CB', 'CG2', 'HG21', 1, -1] , - ['OG1', 'CB', 'CG2', 'HG22', 1, -1] , - ['OG1', 'CB', 'CG2', 'HG23', 1, -1] , - ['CG2', 'CB', 'OG1', 'HG1', 1, -1] , - ['C', 'CA', 'CB', 'CG2', 1, -1] , - ), - 'VAL' : ( - ['N', 'CA', 'CB', 'HB', 1, -1] , - ['N', 'CA', 'CB', 'CG1', 1, -1] , - ['N', 'CA', 'CB', 'CG2', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'CG1', 'HG11', 1, -1] , - ['CA', 'CB', 'CG1', 'HG12', 1, -1] , - ['CA', 'CB', 'CG1', 'HG13', 1, -1] , - ['CA', 'CB', 'CG2', 'HG21', 1, 2] , - ['CA', 'CB', 'CG2', 'HG22', 1, -1] , - ['CA', 'CB', 'CG2', 'HG23', 1, -1] , - ['HA', 'CA', 'CB', 'HB', 1, -1] , - ['HA', 'CA', 'CB', 'CG1', 1, -1] , - ['HA', 'CA', 'CB', 'CG2', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['C', 'CA', 'CB', 'HB', 1, -1] , - ['HB', 'CB', 'CG1', 'HG11', 1, -1] , - ['HB', 'CB', 'CG1', 'HG12', 1, -1] , - ['HB', 'CB', 'CG1', 'HG13', 1, -1] , - ['HB', 'CB', 'CG2', 'HG21', 1, -1] , - ['HB', 'CB', 'CG2', 'HG22', 1, -1] , - ['HB', 'CB', 'CG2', 'HG23', 1, -1] , - ['C', 'CA', 'CB', 'CG1', 1, -1] , - ['CG1', 'CB', 'CG2', 'HG21', 1, -1] , - ['CG1', 'CB', 'CG2', 'HG22', 1, -1] , - ['CG1', 'CB', 'CG2', 'HG23', 1, -1] , - ['CG2', 'CB', 'CG1', 'HG11', 1, -1] , - ['CG2', 'CB', 'CG1', 'HG12', 1, -1] , - ['CG2', 'CB', 'CG1', 'HG13', 1, -1] , - ['C', 'CA', 'CB', 'CG2', 1, -1] , - ), - 'TRP' : ( - ['N', 'CA', 'CB', 'HB1', 1, -1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'CG', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'CG', 'CD1', 1, -1] , - ['CA', 'CB', 'CG', 'CD2', 1, 2] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'CG', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CG', 'CD1', 'HD1', 0, -1] , - ['CB', 'CG', 'CD1', 'NE1', 0, 3] , - ['CB', 'CG', 'CD2', 'CE2', 0, -1] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'CG', 'CD1', 1, -1] , - ['HB1', 'CB', 'CG', 'CD2', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'CG', 'CD1', 1, -1] , - ['HB2', 'CB', 'CG', 'CD2', 1, -1] , - ['C', 'CA', 'CB', 'CG', 1, -1] , - ['CG', 'CD1', 'NE1', 'HE1', 0, 4] , - ['CG', 'CD2', 'CE2', 'CZ2', 0, 4] , - ['CD1', 'CG', 'CD2', 'CE2', 0, -1] , - ['CD2', 'CG', 'CD1', 'HD1', 0, -1] , - ['HD1', 'CD1', 'NE1', 'HE1', 0, -1] , - ['CD2', 'CG', 'CD1', 'NE1', 0, -1] , - ['CD2', 'CE2', 'CZ2', 'HZ2', 0, -1] , - ['CD2', 'CE2', 'CZ2', 'CH2', 0, 5] , - ['CE2', 'CZ2', 'CH2', 'HH2', 0, 6] , - ['HE3', 'CE3', 'CZ3', 'HZ3', 0, -1] , - ['HZ2', 'CZ2', 'CH2', 'HH2', 0, -1] , - ), - 'TYR' : ( - ['N', 'CA', 'CB', 'HB1', 1, -1] , - ['N', 'CA', 'CB', 'HB2', 1, -1] , - ['N', 'CA', 'CB', 'CG', 1, 1] , - ['N', 'CA', 'C', 'O', 1, 0] , - ['H', 'N', 'CA', 'HA', 1, -1] , - ['H', 'N', 'CA', 'CB', 1, -1] , - ['C', 'CA', 'N', 'H', 1, -1] , - ['CA', 'CB', 'CG', 'CD1', 1, 2] , - ['CA', 'CB', 'CG', 'CD2', 1, -1] , - ['HA', 'CA', 'CB', 'HB1', 1, -1] , - ['HA', 'CA', 'CB', 'HB2', 1, -1] , - ['HA', 'CA', 'CB', 'CG', 1, -1] , - ['HA', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CA', 'C', 'O', 1, -1] , - ['CB', 'CG', 'CD1', 'HD1', 0, -1] , - ['CB', 'CG', 'CD1', 'CE1', 0, 3] , - ['CB', 'CG', 'CD2', 'HD2', 0, -1] , - ['CB', 'CG', 'CD2', 'CE2', 0, -1] , - ['C', 'CA', 'CB', 'HB1', 1, -1] , - ['HB1', 'CB', 'CG', 'CD1', 1, -1] , - ['HB1', 'CB', 'CG', 'CD2', 1, -1] , - ['C', 'CA', 'CB', 'HB2', 1, -1] , - ['HB2', 'CB', 'CG', 'CD1', 1, -1] , - ['HB2', 'CB', 'CG', 'CD2', 1, -1] , - ['C', 'CA', 'CB', 'CG', 1, -1] , - ['CG', 'CD1', 'CE1', 'HE1', 0, -1] , - ['CG', 'CD1', 'CE1', 'CZ', 0, 4] , - ['CG', 'CD2', 'CE2', 'HE2', 0, -1] , - ['CG', 'CD2', 'CE2', 'CZ', 0, -1] , - ['CD1', 'CG', 'CD2', 'HD2', 0, -1] , - ['CD1', 'CG', 'CD2', 'CE2', 0, -1] , - ['CD1', 'CE1', 'CZ', 'CE2', 0, 5] , - ['CD1', 'CE1', 'CZ', 'OH', 0, -1] , - ['CD2', 'CG', 'CD1', 'HD1', 0, -1] , - ['HD1', 'CD1', 'CE1', 'HE1', 0, -1] , - ['HD1', 'CD1', 'CE1', 'CZ', 0, -1] , - ['CD2', 'CG', 'CD1', 'CE1', 0, -1] , - ['CD2', 'CE2', 'CZ', 'CE1', 0, -1] , - ['CD2', 'CE2', 'CZ', 'OH', 0, -1] , - ['HD2', 'CD2', 'CE2', 'HE2', 0, -1] , - ['HD2', 'CD2', 'CE2', 'CZ', 0, -1] , - ['CE1', 'CZ', 'CE2', 'HE2', 0, -1] , - ['CE1', 'CZ', 'OH', 'HH', 1, 6] , - ['CE2', 'CZ', 'CE1', 'HE1', 0, -1] , - ['HE1', 'CE1', 'CZ', 'OH', 0, -1] , - ['CE2', 'CZ', 'OH', 'HH', 1, -1] , - ['HE2', 'CE2', 'CZ', 'OH', 0, -1] , - ), - } + 'SP2' : ( + ['N', 'CA', 'CB', 'HB1', 1, -1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'OG', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'OG', 'PD', 1, 2] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'OG', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'OG', 'PD', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'OG', 'PD', 1, -1] , + ['C', 'CA', 'CB', 'OG', 1, -1] , + ['CB', 'OG', 'PD', 'OE1', 1, 3] , + ['CB', 'OG', 'PD', 'OE2', 1, -1] , + ['CB', 'OG', 'PD', 'OE', 1, -1] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'OG', 'PD', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'OG', 'PD', 1, -1] , + ['C', 'CA', 'CB', 'CG', 1, -1] , + ), + 'SEP' : ( + ['N', 'CA', 'CB', 'HB1', 1, -1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'OG', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'OG', 'P', 1, 2] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'OG', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'OG', 'P', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'OG', 'P', 1, -1] , + ['C', 'CA', 'CB', 'OG', 1, -1] , + ['CB', 'OG', 'P', 'O1P', 1, 3] , + ['CB', 'OG', 'P', 'O2P', 1, -1] , + ['CB', 'OG', 'P', 'O3P', 1, -1] , + ), + 'THR' : ( + ['N', 'CA', 'CB', 'HB', 1, -1] , + ['N', 'CA', 'CB', 'OG1', 1, 1] , + ['N', 'CA', 'CB', 'CG2', 1, -1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'OG1', 'HG1', 1, 2] , + ['CA', 'CB', 'CG2', 'HG21', 1, -1] , + ['CA', 'CB', 'CG2', 'HG22', 1, -1] , + ['CA', 'CB', 'CG2', 'HG23', 1, -1] , + ['HA', 'CA', 'CB', 'HB', 1, -1] , + ['HA', 'CA', 'CB', 'OG1', 1, -1] , + ['HA', 'CA', 'CB', 'CG2', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['C', 'CA', 'CB', 'HB', 1, -1] , + ['HB', 'CB', 'OG1', 'HG1', 1, -1] , + ['HB', 'CB', 'CG2', 'HG21', 1, -1] , + ['HB', 'CB', 'CG2', 'HG22', 1, -1] , + ['HB', 'CB', 'CG2', 'HG23', 1, -1] , + ['C', 'CA', 'CB', 'OG1', 1, -1] , + ['OG1', 'CB', 'CG2', 'HG21', 1, -1] , + ['OG1', 'CB', 'CG2', 'HG22', 1, -1] , + ['OG1', 'CB', 'CG2', 'HG23', 1, -1] , + ['CG2', 'CB', 'OG1', 'HG1', 1, -1] , + ['C', 'CA', 'CB', 'CG2', 1, -1] , + ), + 'VAL' : ( + ['N', 'CA', 'CB', 'HB', 1, -1] , + ['N', 'CA', 'CB', 'CG1', 1, -1] , + ['N', 'CA', 'CB', 'CG2', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'CG1', 'HG11', 1, -1] , + ['CA', 'CB', 'CG1', 'HG12', 1, -1] , + ['CA', 'CB', 'CG1', 'HG13', 1, -1] , + ['CA', 'CB', 'CG2', 'HG21', 1, 2] , + ['CA', 'CB', 'CG2', 'HG22', 1, -1] , + ['CA', 'CB', 'CG2', 'HG23', 1, -1] , + ['HA', 'CA', 'CB', 'HB', 1, -1] , + ['HA', 'CA', 'CB', 'CG1', 1, -1] , + ['HA', 'CA', 'CB', 'CG2', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['C', 'CA', 'CB', 'HB', 1, -1] , + ['HB', 'CB', 'CG1', 'HG11', 1, -1] , + ['HB', 'CB', 'CG1', 'HG12', 1, -1] , + ['HB', 'CB', 'CG1', 'HG13', 1, -1] , + ['HB', 'CB', 'CG2', 'HG21', 1, -1] , + ['HB', 'CB', 'CG2', 'HG22', 1, -1] , + ['HB', 'CB', 'CG2', 'HG23', 1, -1] , + ['C', 'CA', 'CB', 'CG1', 1, -1] , + ['CG1', 'CB', 'CG2', 'HG21', 1, -1] , + ['CG1', 'CB', 'CG2', 'HG22', 1, -1] , + ['CG1', 'CB', 'CG2', 'HG23', 1, -1] , + ['CG2', 'CB', 'CG1', 'HG11', 1, -1] , + ['CG2', 'CB', 'CG1', 'HG12', 1, -1] , + ['CG2', 'CB', 'CG1', 'HG13', 1, -1] , + ['C', 'CA', 'CB', 'CG2', 1, -1] , + ), + 'TRP' : ( + ['N', 'CA', 'CB', 'HB1', 1, -1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'CG', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'CG', 'CD1', 1, -1] , + ['CA', 'CB', 'CG', 'CD2', 1, 2] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'CG', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CG', 'CD1', 'HD1', 0, -1] , + ['CB', 'CG', 'CD1', 'NE1', 0, 3] , + ['CB', 'CG', 'CD2', 'CE2', 0, -1] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'CG', 'CD1', 1, -1] , + ['HB1', 'CB', 'CG', 'CD2', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'CG', 'CD1', 1, -1] , + ['HB2', 'CB', 'CG', 'CD2', 1, -1] , + ['C', 'CA', 'CB', 'CG', 1, -1] , + ['CG', 'CD1', 'NE1', 'HE1', 0, 4] , + ['CG', 'CD2', 'CE2', 'CZ2', 0, 4] , + ['CD1', 'CG', 'CD2', 'CE2', 0, -1] , + ['CD2', 'CG', 'CD1', 'HD1', 0, -1] , + ['HD1', 'CD1', 'NE1', 'HE1', 0, -1] , + ['CD2', 'CG', 'CD1', 'NE1', 0, -1] , + ['CD2', 'CE2', 'CZ2', 'HZ2', 0, -1] , + ['CD2', 'CE2', 'CZ2', 'CH2', 0, 5] , + ['CE2', 'CZ2', 'CH2', 'HH2', 0, 6] , + ['HE3', 'CE3', 'CZ3', 'HZ3', 0, -1] , + ['HZ2', 'CZ2', 'CH2', 'HH2', 0, -1] , + ), + 'TYR' : ( + ['N', 'CA', 'CB', 'HB1', 1, -1] , + ['N', 'CA', 'CB', 'HB2', 1, -1] , + ['N', 'CA', 'CB', 'CG', 1, 1] , + ['N', 'CA', 'C', 'O', 1, 0] , + ['H', 'N', 'CA', 'HA', 1, -1] , + ['H', 'N', 'CA', 'CB', 1, -1] , + ['C', 'CA', 'N', 'H', 1, -1] , + ['CA', 'CB', 'CG', 'CD1', 1, 2] , + ['CA', 'CB', 'CG', 'CD2', 1, -1] , + ['HA', 'CA', 'CB', 'HB1', 1, -1] , + ['HA', 'CA', 'CB', 'HB2', 1, -1] , + ['HA', 'CA', 'CB', 'CG', 1, -1] , + ['HA', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CA', 'C', 'O', 1, -1] , + ['CB', 'CG', 'CD1', 'HD1', 0, -1] , + ['CB', 'CG', 'CD1', 'CE1', 0, 3] , + ['CB', 'CG', 'CD2', 'HD2', 0, -1] , + ['CB', 'CG', 'CD2', 'CE2', 0, -1] , + ['C', 'CA', 'CB', 'HB1', 1, -1] , + ['HB1', 'CB', 'CG', 'CD1', 1, -1] , + ['HB1', 'CB', 'CG', 'CD2', 1, -1] , + ['C', 'CA', 'CB', 'HB2', 1, -1] , + ['HB2', 'CB', 'CG', 'CD1', 1, -1] , + ['HB2', 'CB', 'CG', 'CD2', 1, -1] , + ['C', 'CA', 'CB', 'CG', 1, -1] , + ['CG', 'CD1', 'CE1', 'HE1', 0, -1] , + ['CG', 'CD1', 'CE1', 'CZ', 0, 4] , + ['CG', 'CD2', 'CE2', 'HE2', 0, -1] , + ['CG', 'CD2', 'CE2', 'CZ', 0, -1] , + ['CD1', 'CG', 'CD2', 'HD2', 0, -1] , + ['CD1', 'CG', 'CD2', 'CE2', 0, -1] , + ['CD1', 'CE1', 'CZ', 'CE2', 0, 5] , + ['CD1', 'CE1', 'CZ', 'OH', 0, -1] , + ['CD2', 'CG', 'CD1', 'HD1', 0, -1] , + ['HD1', 'CD1', 'CE1', 'HE1', 0, -1] , + ['HD1', 'CD1', 'CE1', 'CZ', 0, -1] , + ['CD2', 'CG', 'CD1', 'CE1', 0, -1] , + ['CD2', 'CE2', 'CZ', 'CE1', 0, -1] , + ['CD2', 'CE2', 'CZ', 'OH', 0, -1] , + ['HD2', 'CD2', 'CE2', 'HE2', 0, -1] , + ['HD2', 'CD2', 'CE2', 'CZ', 0, -1] , + ['CE1', 'CZ', 'CE2', 'HE2', 0, -1] , + ['CE1', 'CZ', 'OH', 'HH', 1, 6] , + ['CE2', 'CZ', 'CE1', 'HE1', 0, -1] , + ['HE1', 'CE1', 'CZ', 'OH', 0, -1] , + ['CE2', 'CZ', 'OH', 'HH', 1, -1] , + ['HE2', 'CE2', 'CZ', 'OH', 0, -1] , + ), + } @@ -5456,5 +5456,3 @@ def pmx_data_file( filename ): ('S.3', 'C.3', '1') , ('C.ar', 'O.3', '1') , ] - - diff --git a/pmx/model.py b/pmx/model.py index c9f6df46..ba169cee 100644 --- a/pmx/model.py +++ b/pmx/model.py @@ -68,15 +68,16 @@ remove chain A >>> model.write(args['-o']) write new structure file """ -from atomselection import * -import sys,copy,library +from .atomselection import * +import sys,copy +from . import library #from chain import * -import chain -from molecule import * -from atom import * -import _pmx as _p -XX = 0 -YY = 1 +from . import chain +from .molecule import * +from .atom import * +from . import _pmx as _p +XX = 0 +YY = 1 ZZ = 2 @@ -84,7 +85,7 @@ class Model(Atomselection): def __init__(self, filename = None, pdbline = None, renumber_atoms=True, renumber_residues = True, bPDBTER= False, bNoNewID=True, bPDBGAP=False, **kwargs): - + Atomselection.__init__(self) self.title = 'PMX MODEL' self.chains = [] @@ -96,7 +97,7 @@ def __init__(self, filename = None, pdbline = None, renumber_atoms=True, self.have_bonds=0 self.box = [ [0,0,0], [0,0,0], [0,0,0] ] self.unity = 'A' - for key, val in kwargs.items(): + for key, val in list(kwargs.items()): setattr(self,key,val) if filename is not None: @@ -117,7 +118,7 @@ def __init__(self, filename = None, pdbline = None, renumber_atoms=True, self.make_chains() self.make_residues() if self.chdic and not self.chains: - for key, val in self.chdic.items(): + for key, val in list(self.chdic.items()): self.chains.append(val) if not self.atoms and not self.residues: self.resl_from_chains() @@ -126,13 +127,13 @@ def __init__(self, filename = None, pdbline = None, renumber_atoms=True, self.renumber_atoms() if renumber_residues: self.renumber_residues() - - + + def __str__(self): s = '< Model: nchain = %d nres = %d natom = %d >' %\ (len(self.chains), len(self.residues), len(self.atoms)) return s - + ## def writePDB(self,fname,title="",nr=1): @@ -153,25 +154,25 @@ def __str__(self): def writePIR( self, filename, title=""): fp = open(filename,"w") if not title: title = '_'.join(self.title.split()) - print >>fp, '>P1;%s' % title - print >>fp, 'sequence:::::::::' + print('>P1;%s' % title, file=fp) + print('sequence:::::::::', file=fp) for i in range( len(self.chains) - 1): - print >>fp, self.chains[i].get_sequence()+'/' - print >>fp, self.chains[-1].get_sequence()+'*' + print(self.chains[i].get_sequence()+'/', file=fp) + print(self.chains[-1].get_sequence()+'*', file=fp) fp.close() def writeFASTA( self, filename, title = ""): fp = open(filename,"w") if not title: title = '_'.join(self.title.split()) if len(self.chains) == 1: - print >>fp, '> %s' % title - print >>fp, self.chains[0].get_sequence() + print('> %s' % title, file=fp) + print(self.chains[0].get_sequence(), file=fp) else: for chain in self.chains: - print >>fp, '> %s_chain_%s' % (title, chain.id ) - print >>fp, chain.get_sequence() - - + print('> %s_chain_%s' % (title, chain.id ), file=fp) + print(chain.get_sequence(), file=fp) + + ## def writeGRO( self, filename, title = ''): ## fp = open(filename,'w') @@ -197,7 +198,7 @@ def writeFASTA( self, filename, title = ""): ## else: ## ff+=gro_format % (atom.x[XX]*fac, atom.x[YY]*fac, atom.x[ZZ]*fac ) ## print >>fp, ff - + ## if self.box[XX][YY] or self.box[XX][ZZ] or self.box[YY][XX] or \ ## self.box[YY][ZZ] or self.box[ZZ][XX] or self.box[ZZ][YY]: ## bTric = False @@ -225,7 +226,7 @@ def write(self,fn, title = '', nr = 1, bPDBTER=False, bAssignChainIDs=False): elif ext == 'fasta': self.writeFASTA( fn, title ) else: - print >>sys.stderr, 'pmx_Error_> Can only write pdb or gro!' + print('pmx_Error_> Can only write pdb or gro!', file=sys.stderr) sys.exit(1) @@ -260,13 +261,13 @@ def make_chains(self): ch.id = atom.chain_id atom.chain = ch ch.atoms.append(atom) - + self.chains.append(ch) for ch in self.chains: ch.model = self idx = ch.id self.chdic[idx] = ch - + def make_residues(self): self.residues = [] for ch in self.chains: @@ -310,7 +311,7 @@ def make_residues(self): for r in ch.residues: r.chain = ch r.chain_id = ch.id - + def __readPDB(self,fname=None, pdbline=None): if pdbline: l = pdbline.split('\n') @@ -327,81 +328,81 @@ def __readPDB(self,fname=None, pdbline=None): self.make_residues() self.unity = 'A' return self - + def __check_if_gap( self, atC, atN ): if atC==None: return(False) if atN.name != 'N': return(False) d = atC - atN - if d > 1.7: # bond + if d > 1.7: # bond return(True) return(False) - + def __readPDBTER(self,fname=None, pdbline=None, bNoNewID=True, bPDBGAP=False): if pdbline: l = pdbline.split('\n') else: l = open(fname,'r').readlines() - chainIDstring = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnoprstuvwxyz123456789' - bNewChain = True - chainID = ' ' - prevID = ' ' + chainIDstring = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnoprstuvwxyz123456789' + bNewChain = True + chainID = ' ' + prevID = ' ' prevAtomName = ' ' prevResID = 0 prevResName = ' ' usedChainIDs = [] atomcount = 1 prevCatom = None - + for line in l: - if 'TER' in line: - bNewChain = True + if 'TER' in line: + bNewChain = True if (line[:4]=='ATOM') or (line[:6]=='HETATM'): a = Atom().readPDBString(line,origID=atomcount) atomcount+=1 -# if (a.chain_id != prevID) and (a.chain_id != ' '): # identify chain change by ID (when no TER is there) - if (a.chain_id != prevID): # identify chain change by ID (when no TER is there) - bNewChain = True +# if (a.chain_id != prevID) and (a.chain_id != ' '): # identify chain change by ID (when no TER is there) + if (a.chain_id != prevID): # identify chain change by ID (when no TER is there) + bNewChain = True if (self.__check_if_gap( prevCatom,a )==True and bPDBGAP==True): bNewChain = True if (a.resnr != prevResID): try: if a.resnr != prevResID+1: - bNewChain = True + bNewChain = True if (prevAtomName == 'OC2') or (prevAtomName == 'OXT') or (prevAtomName == 'OT2'): bNewChain = True if (prevAtomName == 'HH33') and ((prevResName=='NME') or (prevResName=='NAC') or (prevResName=='CT3')): # NME cap bNewChain = True except TypeError: bNewChain = False - prevID = a.chain_id + prevID = a.chain_id prevResID = a.resnr prevAtomName = a.name prevResName = a.resname if a.name == 'C': prevCatom = a - if bNewChain==True: - if (a.chain_id==' ') or (a.chain_id==chainID) or (a.chain_id in usedChainIDs): + if bNewChain==True: + if (a.chain_id==' ') or (a.chain_id==chainID) or (a.chain_id in usedChainIDs): #print a.chain_id,a,chainID,usedChainIDs - # find a new chain id - bFound = False - while bFound==False: - foo = chainIDstring[0] - chainIDstring = chainIDstring.lstrip(chainIDstring[0]) - if foo not in usedChainIDs: - bFound=True - chainID = foo - if bNoNewID==True: - chainID = "pmx"+foo - usedChainIDs.append(chainID) - else: - chainID = a.chain_id - usedChainIDs.append(chainID) - a.chain_id = chainID + # find a new chain id + bFound = False + while bFound==False: + foo = chainIDstring[0] + chainIDstring = chainIDstring.lstrip(chainIDstring[0]) + if foo not in usedChainIDs: + bFound=True + chainID = foo + if bNoNewID==True: + chainID = "pmx"+foo + usedChainIDs.append(chainID) + else: + chainID = a.chain_id + usedChainIDs.append(chainID) + a.chain_id = chainID self.atoms.append(a) - bNewChain = False + bNewChain = False if line[:6] == 'CRYST1': self.box = _p.box_from_cryst1( line ) @@ -412,7 +413,7 @@ def __readPDBTER(self,fname=None, pdbline=None, bNoNewID=True, bPDBGAP=False): # chain with a new ID if 'pmx' in a.chain_id: # this ID has already been encountered - if a.chain_id in newChainDict.keys(): + if a.chain_id in list(newChainDict.keys()): a.chain_id = newChainDict[a.chain_id] # ID not yet encountered else: @@ -495,21 +496,21 @@ def __readGRO(self, filename): def read(self, filename, bPDBTER=False, bNoNewID=True, bPDBGAP=False ): ext = filename.split('.')[-1] if ext == 'pdb': - if bPDBTER: + if bPDBTER: return self.__readPDBTER( filename, None, bNoNewID, bPDBGAP ) - else: + else: return self.__readPDB( filename ) elif ext == 'gro': return self.__readGRO( filename ) else: - print >>sys.stderr, 'ERROR: Can only read pdb or gro!' + print('ERROR: Can only read pdb or gro!', file=sys.stderr) sys.exit(1) def renumber_residues(self): for i, res in enumerate(self.residues): res.set_orig_resid( res.id ) res.set_resid(i+1) - + def remove_atom(self,atom): m = atom.molecule @@ -520,9 +521,9 @@ def remove_residue(self,residue): ch.remove_residue(residue) def remove_chain(self,key): - if not self.chdic.has_key(key): - print 'No chain %s to remove....' % key - print 'No changes applied.' + if key not in self.chdic: + print('No chain %s to remove....' % key) + print('No changes applied.') return for ch in self.chains: if ch.id == key: @@ -533,16 +534,16 @@ def remove_chain(self,key): self.al_from_resl() self.renumber_residues() self.renumber_atoms() - + def __delitem__(self,key): self.remove_chain(key) - + ## def insert_sequence(self,pos,new_chain,chain_id): ## """insert a sequence""" ## ch = self.chdic[chain_id] ## ch.insert_chain(pos,new_chain) - + def insert_residue(self,pos,res,chain_id): ch = self.chdic[chain_id] @@ -551,11 +552,11 @@ def insert_residue(self,pos,res,chain_id): def replace_residue(self,residue,new,bKeepResNum=False): ch = residue.chain ch.replace_residue(residue,new,bKeepResNum) - + def insert_chain(self,pos,new_chain): - if self.chdic.has_key(new_chain.id): - print 'Chain identifier %s already in use!' % new_chain.id - print 'Changing chain identifier to 0' + if new_chain.id in self.chdic: + print('Chain identifier %s already in use!' % new_chain.id) + print('Changing chain identifier to 0') new_chain.set_chain_id('0') self.chains.insert(pos,new_chain) self.resl_from_chains() @@ -564,14 +565,14 @@ def insert_chain(self,pos,new_chain): self.make_residues() self.renumber_atoms() self.renumber_residues() - + def append(self,new_chain): """ we assume chain is a Chain""" idx = len(self.chains) self.insert_chain(idx,new_chain) - - + + def fetch_residues(self,key, inv=False): if not hasattr(key,"append"): key = [key] @@ -585,7 +586,7 @@ def fetch_residues(self,key, inv=False): if r.resname not in key: result.append(r) return result - + def fetch_residues_by_ID(self, ind): for r in self.residues: if r.id == ind: @@ -597,19 +598,19 @@ def al_from_resl(self): for r in self.residues: for atom in r.atoms: self.atoms.append(atom) - + def resl_from_chains(self): self.residues = [] for ch in self.chains: for r in ch.residues: self.residues.append(r) - + def copy(self): return copy.deepcopy(self) - + ## def get_bonded(self): ## for ch in self.chains: ## ch.get_bonded() @@ -643,7 +644,7 @@ def copy(self): ## at3.b14.append(atom) - + ## def get_connections(self,cutoff=.8): ## if self.atoms[0].symbol == '': ## self.get_symbol() @@ -662,27 +663,27 @@ def copy(self): ## print 'Error: Number of atoms in trajectory\n \ ## doesn\'t match topology\n' ## sys.exit(1) - + ## for i in range(nat): ## self.atoms[i].x=frame['x'][i] ## self.box = frame['box'] - + def get_mol2_types(self): if self.atoms[0].symbol == '': self.get_symbol() for ch in self.chains: ch.get_mol2_types() - + def get_mol2_resname(self): for ch in self.chains: ch.get_mol2_resname() - + def get_nterms(self): nter = [] for ch in model.chains: first = ch.residues[0] # first residue - if first.resname in library._one_letter.keys(): + if first.resname in list(library._one_letter.keys()): nter.append(first) return nter @@ -690,7 +691,7 @@ def get_cterms(self): cter = [] for ch in model.chains: last = ch.residues[-1] # last residue - if last.resname in library._one_letter.keys(): + if last.resname in list(library._one_letter.keys()): cter.append(last) return last @@ -702,12 +703,4 @@ def residue(self, idx): return self.residues[idx-1] def chain(self, iden): - return self.chdic[iden] - - - - - - - - + return self.chdic[iden] diff --git a/pmx/molecule.py b/pmx/molecule.py index 280da710..dfcd907c 100644 --- a/pmx/molecule.py +++ b/pmx/molecule.py @@ -53,13 +53,14 @@ . """ import sys -from atomselection import * -import library, copy -from rotamer import _aa_chi +from .atomselection import * +import copy +from . import library +from .rotamer import _aa_chi class Molecule(Atomselection): """ Storage class for a Molecule/residue""" - + def __init__(self, **kwargs): Atomselection.__init__(self) self.natoms = 0 @@ -72,7 +73,7 @@ def __init__(self, **kwargs): self.model = None self.chain_id = '' self.id = 0 - for key, val in kwargs.items(): + for key, val in list(kwargs.items()): setattr(self,key,val) def __str__(self): @@ -100,7 +101,7 @@ def has_atom( self, atom_name ): return True else: return False - + def new_aa(self, aa, hydrogens = True): aa = aa.upper() if len(aa) == 1: @@ -134,7 +135,7 @@ def get_real_resname(self): 'HSD':'HIS','HISH':'HIS','HISD':'HIS','ASH':'ASP','ASPP':'ASP','ASPH':'ASP', 'GLH':'GLU','GLUH':'GLU','GLUP':'GLU','SEP':'SEP','SEQ':'SEQ', } - if dic.has_key(self.resname): self.real_resname = dic[self.resname] + if self.resname in dic: self.real_resname = dic[self.resname] else: self.real_resname = self.resname def get_psi(self, degree = False): @@ -180,7 +181,7 @@ def set_psi_down( self, degree, propagate = True ): rot_atoms.append( atom ) for atom in rot_atoms: atom.x = R.apply(atom.x, diff) - + def get_phi(self,degree=False): @@ -192,7 +193,7 @@ def get_phi(self,degree=False): previous = self.chain.residues[chidx-1] C = previous.fetchm(['C'])[0] N,CA,C2 = self.fetchm(['N','CA','C']) - dih = C.dihedral(N,CA,C2) + dih = C.dihedral(N,CA,C2) if not degree: return dih else: @@ -229,7 +230,7 @@ def set_phi_down(self, degree, propagate = True ): rot_atoms.append( atom ) for atom in rot_atoms: atom.x = R.apply(atom.x, diff) - + def get_omega(self,degree=False): @@ -240,7 +241,7 @@ def get_omega(self,degree=False): next_mol = self.chain.residues[chidx+1] CA,C = self.fetchm(['CA','C']) N,CA2 = next_mol.fetchm(['N','CA']) - dih = CA.dihedral(C,N,CA2) + dih = CA.dihedral(C,N,CA2) if not degree: return dih else: @@ -283,7 +284,7 @@ def set_omega_down(self, degree): rot_atoms.append( atom ) for atom in rot_atoms: atom.x = R.apply(atom.x, diff) - + def nchi(self): self.get_real_resname() @@ -302,7 +303,7 @@ def get_chi(self, chi, degree = False ): return dih*180./pi def set_chi(self, chi, phi): - if chi > self.nchi(): return + if chi > self.nchi(): return ang = self.get_chi(chi) dih_atoms = self.fetchm( _aa_chi[self.real_resname][chi][0] ) rot_atoms = self.fetch_atoms( _aa_chi[self.real_resname][chi][1] ) @@ -317,12 +318,12 @@ def set_conformation(self, rotamer): for chi in range(nchi): self.set_chi(chi+1, rotamer[chi+1]) - + def set_resname(self,resname): self.resname = resname for atom in self.atoms: atom.resname = resname - + def set_resid(self,resid): self.id = resid for atom in self.atoms: @@ -336,11 +337,11 @@ def set_chain(self,chain): self.chain = chain for atom in self.atoms: atom.chain = chain - + def set_molecule(self): for atom in self.atoms: atom.molecule = self - + def set_chain_id(self,chain_id): self.chain_id = chain_id for atom in self.atoms: @@ -349,8 +350,8 @@ def set_chain_id(self,chain_id): def insert_atom(self,pos,atom,id=True): """ insert atom at a certain position""" - if pos not in range(len(self.atoms)+1): - print 'Molecule has only %d atoms' % len(self.atoms) + if pos not in list(range(len(self.atoms)+1)): + print('Molecule has only %d atoms' % len(self.atoms)) return else: if id: @@ -363,7 +364,7 @@ def insert_atom(self,pos,atom,id=True): idx_model = self.model.atoms.index(at)+1 if self.chain is not None: idx_chain = self.chain.atoms.index(at)+1 - + else: at = self.atoms[pos] if self.model is not None: @@ -401,7 +402,7 @@ def fetch(self,key,how='byname',wildcard=False): if atom.symbol == key: result.append(atom) return result - + def fetchm(self,keys,how='byname'): """select list of atom by name or element""" result = [] @@ -424,7 +425,7 @@ def remove_atom(self,atom): if self.model is not None: have_model = True else: have_model = False - + aidx = self.atoms.index(atom) if have_chain: chidx = self.chain.atoms.index(atom) @@ -440,7 +441,7 @@ def remove_atom(self,atom): def append(self,atom): """ attach atom at the end""" if not isinstance(atom,Atom): - raise TypeError, "%s is not an Atom instance" % str(atom) + raise TypeError("%s is not an Atom instance" % str(atom)) else: n = len(self.atoms) if n == 0: @@ -462,11 +463,11 @@ def get_bonded(self): if (n1,n2) in bl or (n2,n1) in bl: atom.bonds.append(at) at.bonds.append(atom) - + def get_mol2_types(self, nterminus = False): - if not library._mol2_types.has_key(self.resname): - print 'No mol2 lib entry for residue %s' % self.resname + if self.resname not in library._mol2_types: + print('No mol2 lib entry for residue %s' % self.resname) sys.exit(1) dic = library._mol2_types[self.resname] for atom in self.atoms: @@ -483,7 +484,7 @@ def get_mol2_types(self, nterminus = False): else: atom.atype = dic[atom.name][0] atom.q = dic[atom.name][1] - + def is_protein_residue(self): if self.resname in library._protein_residues: return True @@ -506,7 +507,7 @@ def __init__(self, lst): self.name = '' self.name2 = '' self.read( lst ) - + def read( self, lst ): self.name = lst[0].strip() self.name2 = lst[1].rstrip() @@ -529,15 +530,15 @@ def read( self, lst ): self.properties[prop]+=line def write( self, fp ): - print >>fp, self.name - print >>fp, self.name2, - print >>fp - print >>fp, self.molfile - for k, v in self.properties.items(): - print >>fp, '>', k - print >>fp, v, - print >>fp, '$$$$' - + print(self.name, file=fp) + print(self.name2, end=' ', file=fp) + print(file=fp) + print(self.molfile, file=fp) + for k, v in list(self.properties.items()): + print('>', k, file=fp) + print(v, end=' ', file=fp) + print('$$$$', file=fp) + class SDFile: @@ -583,7 +584,7 @@ def __init__(self, lines): self.__get_keys(lines) self.read(lines) - + def __get_keys(self,lines): for line in lines: if line.startswith('@'): @@ -609,10 +610,10 @@ def __parse_molecule(self): self.num_substr = self.counts[2] self.num_feat = self.counts[3] self.num_sets = self.counts[4] - + self.mol_type = lines[2].strip() self.charge_type = lines[3].strip() - + def __parse_atoms(self): for line in self.atom_lines: @@ -631,28 +632,28 @@ def __parse_bonds(self): atom2 = self.atom_by_id( e[2] ) bond_type = e[3] if atom1 is None or atom2 is None: - print >>sys.stderr,'Mol2Molecule: Error in bond parsing' + print('Mol2Molecule: Error in bond parsing', file=sys.stderr) sys.exit(1) self.bonds.append( [atom1, atom2, bond_type] ) def write(self, fp = sys.stdout): - print >>fp, '@MOLECULE' - print >>fp, self.name - print >>fp, self.num_atoms, self.num_bonds, self.num_substr, self.num_feat, self.num_sets - print >>fp, self.mol_type - print >>fp, self.charge_type - print >>fp - print >>fp, '@ATOM' + print('@MOLECULE', file=fp) + print(self.name, file=fp) + print(self.num_atoms, self.num_bonds, self.num_substr, self.num_feat, self.num_sets, file=fp) + print(self.mol_type, file=fp) + print(self.charge_type, file=fp) + print(file=fp) + print('@ATOM', file=fp) for atom in self.atoms: - print >>fp, "%7d %-8s %9.4f %9.4f %9.4f %-6s %3d %-8s %9.4f" %\ + print("%7d %-8s %9.4f %9.4f %9.4f %-6s %3d %-8s %9.4f" %\ (atom.id, atom.symbol, atom.x[0], atom.x[1], atom.x[2], atom.atype,\ - atom.resnr, atom.resname, atom.q) - print >>fp, '@BOND' + atom.resnr, atom.resname, atom.q), file=fp) + print('@BOND', file=fp) for i, b in enumerate(self.bonds): - print >>fp, "%6d %6d %6d %6s" % ((i+1), b[0].id, b[1].id, b[2]) + print("%6d %6d %6d %6s" % ((i+1), b[0].id, b[1].id, b[2]), file=fp) for line in self.footer: - print >>fp, line - + print(line, file=fp) + def add_atom( self, atom ): n = len(self.atoms)+1 atom.id = n @@ -660,11 +661,11 @@ def add_atom( self, atom ): atom.rename = self.atoms[0].resname self.num_atoms+=1 self.atoms.append( atom ) - + def add_bond(self, bond ): self.num_bonds+=1 self.bonds.append( bond ) - + class Mol2File: @@ -702,5 +703,3 @@ def write(self,fn=None): m.write( fp ) if file_opened: fp.close() - - diff --git a/pmx/mutdb.py b/pmx/mutdb.py index 69118fdd..17974eb1 100644 --- a/pmx/mutdb.py +++ b/pmx/mutdb.py @@ -31,10 +31,10 @@ Functions to read the mutation database """ import sys,os -from model import Model -from atom import Atom -from molecule import Molecule -from parser import * +from .model import Model +from .atom import Atom +from .molecule import Molecule +from .parser import * def read_mutpdb(filename='mutations_oplsaa.pdb'): if not hasattr(filename,"read"): @@ -57,7 +57,7 @@ def read_new_mtp_entry( entry, filename = 'mutres.mtp'): lst = open(filename).readlines() else: lst = filename.readlines() - + lst = kickOutComments(lst,';') key = '[ '+entry+' ]' keyw = ('[ morphes ]', '[ atoms ]','[ impropers ]','[ dihedrals ]',\ @@ -85,7 +85,7 @@ def read_new_mtp_entry( entry, filename = 'mutres.mtp'): 'n1':n1, 't1':t1, } - atoms = [] + atoms = [] al = readSection(res,'[ atoms ]','[') for i, line in enumerate(al): entr = line.split() @@ -131,7 +131,7 @@ def read_new_mtp_entry( entry, filename = 'mutres.mtp'): bonds = [] return mol, bonds, imps, diheds, rotdic - + def read_mtp_entry(entry,filename='ffamber99sb.mtp', version = 'old'): @@ -141,7 +141,7 @@ def read_mtp_entry(entry,filename='ffamber99sb.mtp', version = 'old'): lst = open(filename).readlines() else: lst = filename.readlines() - + lst = kickOutComments(lst,';') key = '[ '+entry+' ]' keyw = ('[ morphes ]', '[ atoms ]','[ bonds ]','[ impropers ]',\ @@ -173,8 +173,8 @@ def read_mtp_entry(entry,filename='ffamber99sb.mtp', version = 'old'): 'r1':r1, 't1':t1, } - - atoms = [] + + atoms = [] al = readSection(res,'[ atoms ]','[') for i, line in enumerate(al): entr = line.split() @@ -234,7 +234,7 @@ def read_mtp(filename = 'ffoplsaa.mtp'): keyw = ('[ atoms ]','[ bonds ]','[ impropers ]',\ '[ dihedrals ]','[ rotations ]') - + entries = [] for line in lst: if line.startswith('[') and line.strip() not in keyw: @@ -243,8 +243,3 @@ def read_mtp(filename = 'ffoplsaa.mtp'): for e in entries: rdic[e] = read_mtp_entry(e,filename) return rdic - - - - - diff --git a/pmx/ndx.py b/pmx/ndx.py index 542ebb36..980db7fc 100644 --- a/pmx/ndx.py +++ b/pmx/ndx.py @@ -27,21 +27,21 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # ---------------------------------------------------------------------- -from parser import * +from .parser import * import re -import sys +import sys #--------------------------------------------------- class IndexGroup: """ CLASS TO DEAL WITH GROMACS INDEX FILES""" def __init__(self, name = '', ids = [], atoms = []): self.ids = [] if atoms: - self.ids = map(lambda a: a.id, atoms ) + self.ids = [a.id for a in atoms] else: self.ids = ids self.name = name self.ids.sort() - + def __str__(self): s = '' s+= '[ %s ]\n' % self.name @@ -115,7 +115,7 @@ def write(self,fn=None,fp=None): if fn: fp = open(fn,'w') for gr in self.groups: - print >>fp, str(gr)+'\n' + print(str(gr)+'\n', file=fp) def __str__(self): @@ -129,8 +129,8 @@ def __getitem__(self, item): def add_group( self, group ): if group.name in self.names: - print >> sys.stderr, "IndexFile has group %s !! " % group.name - print >> sys.stderr, "Group %s will be replaced !!" % group.name + print("IndexFile has group %s !! " % group.name, file=sys.stderr) + print("Group %s will be replaced !!" % group.name, file=sys.stderr) self.delete_group( group.name ) self.names.append( group.name ) self.groups.append( group ) @@ -149,8 +149,8 @@ def delete_group( self, name ): def __delitem__(self, item ): self.delete_group( item ) - - + + #--------------------------------------------------- @@ -158,26 +158,22 @@ def __delitem__(self, item ): def get_index(atom_list = None, residue_list = None, chain_list = None): """ return atom indices from a list of atoms/residues/chains""" if not atom_list and not residue_list and not chain_list: - print 'Error: Need list~' + print('Error: Need list~') sys.exit(1) if atom_list: - lst = map(lambda a: a.id, atom_list) + lst = [a.id for a in atom_list] return lst if residue_list: al = [] - map(lambda r: al.extend(r.atoms), residue_list) + list(map(lambda r: al.extend(r.atoms), residue_list)) return get_index(atom_list = al) if chain_list: al = [] - map(lambda c: al.extend(c.atoms), chain_list) + list(map(lambda c: al.extend(c.atoms), chain_list)) return get_index(atom_list = al) - - + + def make_index_group(atomlist, name): lst = get_index(atomlist) g = IndexGroup(ids = lst, name = name) return g - - - - diff --git a/pmx/odict.py b/pmx/odict.py index 3c83d256..6a2faefd 100644 --- a/pmx/odict.py +++ b/pmx/odict.py @@ -15,7 +15,7 @@ # Comments, suggestions and bug reports welcome. """A dict that keeps keys in insertion order""" -from __future__ import generators + __author__ = ('Nicola Larosa ,' 'Michael Foord ') @@ -38,40 +38,40 @@ class OrderedDict(dict): """ A class of dictionary that keeps the insertion order of keys. - + All appropriate methods return keys, items, or values in an ordered way. - + All normal dictionary methods are available. Update and comparison is restricted to other OrderedDict objects. - + Various sequence methods are available, including the ability to explicitly mutate the key ordering. - + __contains__ tests: - + >>> d = OrderedDict(((1, 3),)) >>> 1 in d 1 >>> 4 in d 0 - + __getitem__ tests: - + >>> OrderedDict(((1, 3), (3, 2), (2, 1)))[2] 1 >>> OrderedDict(((1, 3), (3, 2), (2, 1)))[4] Traceback (most recent call last): KeyError: 4 - + __len__ tests: - + >>> len(OrderedDict()) 0 >>> len(OrderedDict(((1, 3), (3, 2), (2, 1)))) 3 - + get tests: - + >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) >>> d.get(1) 3 @@ -81,9 +81,9 @@ class OrderedDict(dict): 5 >>> d OrderedDict([(1, 3), (3, 2), (2, 1)]) - + has_key tests: - + >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) >>> d.has_key(1) 1 @@ -95,11 +95,11 @@ def __init__(self, init_val=(), strict=False): """ Create a new ordered dictionary. Cannot init from a normal dict, nor from kwargs, since items order is undefined in those cases. - + If the ``strict`` keyword argument is ``True`` (``False`` is the default) then when doing slice assignment - the ``OrderedDict`` you are assigning from *must not* contain any keys in the remaining dict. - + >>> OrderedDict() OrderedDict([]) >>> OrderedDict({1: 1}) @@ -116,7 +116,7 @@ def __init__(self, init_val=(), strict=False): self.strict = strict dict.__init__(self) if isinstance(init_val, OrderedDict): - self._sequence = init_val.keys() + self._sequence = list(init_val.keys()) dict.update(self, init_val) elif isinstance(init_val, dict): # we lose compatibility with other ordered dict types this way @@ -143,7 +143,7 @@ def __delitem__(self, key): >>> d OrderedDict([(2, 1), (3, 2)]) """ - if isinstance(key, types.SliceType): + if isinstance(key, slice): # FIXME: efficiency? keys = self._sequence[key] for entry in keys: @@ -174,7 +174,7 @@ def __eq__(self, other): if isinstance(other, OrderedDict): # FIXME: efficiency? # Generate both item lists for each compare - return (self.items() == other.items()) + return (list(self.items()) == list(other.items())) else: return False @@ -194,7 +194,7 @@ def __lt__(self, other): raise TypeError('Can only compare with other OrderedDicts') # FIXME: efficiency? # Generate both item lists for each compare - return (self.items() < other.items()) + return (list(self.items()) < list(other.items())) def __le__(self, other): """ @@ -215,7 +215,7 @@ def __le__(self, other): raise TypeError('Can only compare with other OrderedDicts') # FIXME: efficiency? # Generate both item lists for each compare - return (self.items() <= other.items()) + return (list(self.items()) <= list(other.items())) def __ne__(self, other): """ @@ -236,7 +236,7 @@ def __ne__(self, other): if isinstance(other, OrderedDict): # FIXME: efficiency? # Generate both item lists for each compare - return not (self.items() == other.items()) + return not (list(self.items()) == list(other.items())) else: return True @@ -256,7 +256,7 @@ def __gt__(self, other): raise TypeError('Can only compare with other OrderedDicts') # FIXME: efficiency? # Generate both item lists for each compare - return (self.items() > other.items()) + return (list(self.items()) > list(other.items())) def __ge__(self, other): """ @@ -277,12 +277,12 @@ def __ge__(self, other): raise TypeError('Can only compare with other OrderedDicts') # FIXME: efficiency? # Generate both item lists for each compare - return (self.items() >= other.items()) + return (list(self.items()) >= list(other.items())) def __repr__(self): """ Used for __repr__ and __str__ - + >>> r1 = repr(OrderedDict((('a', 'b'), ('c', 'd'), ('e', 'f')))) >>> r1 "OrderedDict([('a', 'b'), ('c', 'd'), ('e', 'f')])" @@ -320,7 +320,7 @@ def __setitem__(self, key, val): >>> d[1:3] = OrderedDict(((1, 2), (5, 6), (7, 8))) >>> d OrderedDict([(0, 1), (1, 2), (5, 6), (7, 8), (3, 4)]) - + >>> a = OrderedDict(((0, 1), (1, 2), (2, 3)), strict=True) >>> a[3] = 4 >>> a @@ -344,24 +344,24 @@ def __setitem__(self, key, val): >>> a[::-1] = OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) >>> a OrderedDict([(3, 4), (2, 3), (1, 2), (0, 1)]) - + >>> d = OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) >>> d[:1] = 3 Traceback (most recent call last): TypeError: slice assignment requires an OrderedDict - + >>> d = OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) >>> d[:1] = OrderedDict([(9, 8)]) >>> d OrderedDict([(9, 8), (1, 2), (2, 3), (3, 4)]) """ - if isinstance(key, types.SliceType): + if isinstance(key, slice): if not isinstance(val, OrderedDict): # FIXME: allow a list of tuples? raise TypeError('slice assignment requires an OrderedDict') keys = self._sequence[key] # NOTE: Could use ``range(*key.indices(len(self._sequence)))`` - indexes = range(len(self._sequence))[key] + indexes = list(range(len(self._sequence)))[key] if key.step is None: # NOTE: new slice may not be the same size as the one being # overwritten ! @@ -369,7 +369,7 @@ def __setitem__(self, key, val): # e.g. d[5:3] pos = key.start or 0 del self[key] - newkeys = val.keys() + newkeys = list(val.keys()) for k in newkeys: if k in self: if self.strict: @@ -390,7 +390,7 @@ def __setitem__(self, key, val): 'to extended slice of size %s' % (len(val), len(keys))) # FIXME: efficiency? del self[key] - item_list = zip(indexes, val.items()) + item_list = list(zip(indexes, list(val.items()))) # smallest indexes first - higher indexes not guaranteed to # exist item_list.sort() @@ -415,7 +415,7 @@ def __getitem__(self, key): >>> type(b[2:4]) """ - if isinstance(key, types.SliceType): + if isinstance(key, slice): # FIXME: does this raise the error we want? keys = self._sequence[key] # FIXME: efficiency? @@ -443,7 +443,7 @@ def __setattr__(self, name, value): def __getattr__(self, name): """ Implemented so that access to ``sequence`` raises a warning. - + >>> d = OrderedDict() >>> d.sequence [] @@ -462,7 +462,7 @@ def __getattr__(self, name): def __deepcopy__(self, memo): """ To allow deepcopy to work with OrderedDict. - + >>> from copy import deepcopy >>> a = OrderedDict([(1, 1), (2, 2), (3, 3)]) >>> a['test'] = {} @@ -475,7 +475,7 @@ def __deepcopy__(self, memo): False """ from copy import deepcopy - return self.__class__(deepcopy(self.items(), memo), self.strict) + return self.__class__(deepcopy(list(self.items()), memo), self.strict) ### Read-only methods ### @@ -489,9 +489,9 @@ def copy(self): def items(self): """ - ``items`` returns a list of tuples representing all the + ``items`` returns a list of tuples representing all the ``(key, value)`` pairs in the dictionary. - + >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) >>> d.items() [(1, 3), (3, 2), (2, 1)] @@ -499,12 +499,12 @@ def items(self): >>> d.items() [] """ - return zip(self._sequence, self.values()) + return list(zip(self._sequence, list(self.values()))) def keys(self): """ Return a list of keys in the ``OrderedDict``. - + >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) >>> d.keys() [1, 3, 2] @@ -514,10 +514,10 @@ def keys(self): def values(self, values=None): """ Return a list of all the values in the OrderedDict. - + Optionally you can pass in a list of values, which will replace the current list. The value list must be the same len as the OrderedDict. - + >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) >>> d.values() [3, 2, 1] @@ -538,9 +538,9 @@ def iteritems(self): StopIteration """ def make_iter(self=self): - keys = self.iterkeys() + keys = iter(self.keys()) while True: - key = keys.next() + key = next(keys) yield (key, self[key]) return make_iter() @@ -575,9 +575,9 @@ def itervalues(self): StopIteration """ def make_iter(self=self): - keys = self.iterkeys() + keys = iter(self.keys()) while True: - yield self[keys.next()] + yield self[next(keys)] return make_iter() ### Read-write methods ### @@ -595,7 +595,7 @@ def clear(self): def pop(self, key, *args): """ No dict.pop in Python 2.2, gotta reimplement it - + >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) >>> d.pop(3) 2 @@ -611,7 +611,7 @@ def pop(self, key, *args): TypeError: pop expected at most 2 arguments, got 3 """ if len(args) > 1: - raise TypeError, ('pop expected at most 2 arguments, got %s' % + raise TypeError('pop expected at most 2 arguments, got %s' % (len(args) + 1)) if key in self: val = self[key] @@ -627,7 +627,7 @@ def popitem(self, i=-1): """ Delete and return an item specified by index, not a random one as in dict. The index is -1 by default (the last item). - + >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) >>> d.popitem() (2, 1) @@ -673,7 +673,7 @@ def setdefault(self, key, defval = None): def update(self, from_od): """ Update from another OrderedDict or sequence of (key, value) pairs - + >>> d = OrderedDict(((1, 0), (0, 1))) >>> d.update(OrderedDict(((1, 3), (3, 2), (2, 1)))) >>> d @@ -686,7 +686,7 @@ def update(self, from_od): TypeError: cannot convert dictionary update sequence element "4" to a 2-item sequence """ if isinstance(from_od, OrderedDict): - for key, val in from_od.items(): + for key, val in list(from_od.items()): self[key] = val elif isinstance(from_od, dict): # we lose compatibility with other ordered dict types this way @@ -705,11 +705,11 @@ def update(self, from_od): def rename(self, old_key, new_key): """ Rename the key for a given value, without modifying sequence order. - + For the case where new_key already exists this raise an exception, since if new_key exists, it is ambiguous as to what happens to the associated values, and the position of new_key in the sequence. - + >>> od = OrderedDict() >>> od['a'] = 1 >>> od['b'] = 2 @@ -731,7 +731,7 @@ def rename(self, old_key, new_key): if new_key in self: raise ValueError("New key already exists: %r" % new_key) # rename sequence entry - value = self[old_key] + value = self[old_key] old_idx = self._sequence.index(old_key) self._sequence[old_idx] = new_key # rename internal dict entry @@ -741,10 +741,10 @@ def rename(self, old_key, new_key): def setitems(self, items): """ This method allows you to set the items in the dict. - + It takes a list of tuples - of the same sort returned by the ``items`` method. - + >>> d = OrderedDict() >>> d.setitems(((3, 1), (2, 3), (1, 2))) >>> d @@ -759,10 +759,10 @@ def setkeys(self, keys): ``setkeys`` all ows you to pass in a new list of keys which will replace the current set. This must contain the same set of keys, but need not be in the same order. - + If you pass in new keys that don't match, a ``KeyError`` will be raised. - + >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) >>> d.keys() [1, 3, 2] @@ -790,9 +790,9 @@ def setvalues(self, values): """ You can pass in a list of values, which will replace the current list. The value list must be the same len as the OrderedDict. - + (Or a ``ValueError`` is raised.) - + >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) >>> d.setvalues((1, 2, 3)) >>> d @@ -805,14 +805,14 @@ def setvalues(self, values): # FIXME: correct error to raise? raise ValueError('Value list is not the same length as the ' 'OrderedDict.') - self.update(zip(self, values)) + self.update(list(zip(self, values))) ### Sequence Methods ### def index(self, key): """ Return the position of the specified key in the OrderedDict. - + >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) >>> d.index(3) 1 @@ -825,10 +825,10 @@ def index(self, key): def insert(self, index, key, value): """ Takes ``index``, ``key``, and ``value`` as arguments. - + Sets ``key`` to ``value``, so that ``key`` is at position ``index`` in the OrderedDict. - + >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) >>> d.insert(0, 4, 0) >>> d @@ -849,7 +849,7 @@ def insert(self, index, key, value): def reverse(self): """ Reverse the order of the OrderedDict. - + >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) >>> d.reverse() >>> d @@ -860,10 +860,10 @@ def reverse(self): def sort(self, *args, **kwargs): """ Sort the key order in the OrderedDict. - + This method takes the same arguments as the ``list.sort`` method on your version of Python. - + >>> d = OrderedDict(((4, 1), (2, 2), (3, 3), (1, 4))) >>> d.sort() >>> d @@ -875,7 +875,7 @@ class Keys(object): # FIXME: should this object be a subclass of list? """ Custom object for accessing the keys of an OrderedDict. - + Can be called like the normal ``OrderedDict.keys`` method, but also supports indexing and sequence methods. """ @@ -896,14 +896,14 @@ def __setitem__(self, index, name): """ You cannot assign to keys, but you can do slice assignment to re-order them. - + You can only do slice assignment if the new set of keys is a reordering of the original set. """ - if isinstance(index, types.SliceType): + if isinstance(index, slice): # FIXME: efficiency? # check length is the same - indexes = range(len(self._main._sequence))[index] + indexes = list(range(len(self._main._sequence)))[index] if len(indexes) != len(name): raise ValueError('attempt to assign sequence of size %s ' 'to slice of size %s' % (len(name), len(indexes))) @@ -917,7 +917,7 @@ def __setitem__(self, index, name): raise KeyError('Keylist is not the same as current keylist.') orig_vals = [self._main[k] for k in name] del self._main[index] - vals = zip(indexes, name, orig_vals) + vals = list(zip(indexes, name, orig_vals)) vals.sort() for i, k, v in vals: if self._main.strict and k in self._main: @@ -938,12 +938,12 @@ def __eq__(self, other): return self._main._sequence == other def __ne__(self, other): return self._main._sequence != other def __gt__(self, other): return self._main._sequence > other def __ge__(self, other): return self._main._sequence >= other - # FIXME: do we need __cmp__ as well as rich comparisons? - def __cmp__(self, other): return cmp(self._main._sequence, other) + # FIXME: __cmp__ not used in python3 + # def __cmp__(self, other): return cmp(self._main._sequence, other) def __contains__(self, item): return item in self._main._sequence def __len__(self): return len(self._main._sequence) - def __iter__(self): return self._main.iterkeys() + def __iter__(self): return iter(self._main.keys()) def count(self, item): return self._main._sequence.count(item) def index(self, item, *args): return self._main._sequence.index(item, *args) def reverse(self): self._main._sequence.reverse() @@ -966,7 +966,7 @@ def extend(self, other): raise TypeError('Can\'t extend keys') class Items(object): """ Custom object for accessing the items of an OrderedDict. - + Can be called like the normal ``OrderedDict.items`` method, but also supports indexing and sequence methods. """ @@ -980,15 +980,15 @@ def __call__(self): def __getitem__(self, index): """Fetch the item at position i.""" - if isinstance(index, types.SliceType): + if isinstance(index, slice): # fetching a slice returns an OrderedDict - return self._main[index].items() + return list(self._main[index].items()) key = self._main._sequence[index] return (key, self._main[key]) def __setitem__(self, index, item): """Set item at position i to item.""" - if isinstance(index, types.SliceType): + if isinstance(index, slice): # NOTE: item must be an iterable (list of tuples) self._main[index] = OrderedDict(item) else: @@ -1005,7 +1005,7 @@ def __setitem__(self, index, item): def __delitem__(self, i): """Delete the item at position i.""" key = self._main._sequence[i] - if isinstance(i, types.SliceType): + if isinstance(i, slice): for k in key: # FIXME: efficiency? del self._main[k] @@ -1013,29 +1013,29 @@ def __delitem__(self, i): del self._main[key] ### following methods pinched from UserList and adapted ### - def __repr__(self): return repr(self._main.items()) + def __repr__(self): return repr(list(self._main.items())) # FIXME: do we need to check if we are comparing with another ``Items`` # object? (like the __cast method of UserList) - def __lt__(self, other): return self._main.items() < other - def __le__(self, other): return self._main.items() <= other - def __eq__(self, other): return self._main.items() == other - def __ne__(self, other): return self._main.items() != other - def __gt__(self, other): return self._main.items() > other - def __ge__(self, other): return self._main.items() >= other - def __cmp__(self, other): return cmp(self._main.items(), other) - - def __contains__(self, item): return item in self._main.items() + def __lt__(self, other): return list(self._main.items()) < other + def __le__(self, other): return list(self._main.items()) <= other + def __eq__(self, other): return list(self._main.items()) == other + def __ne__(self, other): return list(self._main.items()) != other + def __gt__(self, other): return list(self._main.items()) > other + def __ge__(self, other): return list(self._main.items()) >= other + # def __cmp__(self, other): return cmp(list(self._main.items()), other) + + def __contains__(self, item): return item in list(self._main.items()) def __len__(self): return len(self._main._sequence) # easier :-) - def __iter__(self): return self._main.iteritems() - def count(self, item): return self._main.items().count(item) - def index(self, item, *args): return self._main.items().index(item, *args) + def __iter__(self): return iter(self._main.items()) + def count(self, item): return list(self._main.items()).count(item) + def index(self, item, *args): return list(self._main.items()).index(item, *args) def reverse(self): self._main.reverse() def sort(self, *args, **kwds): self._main.sort(*args, **kwds) - def __mul__(self, n): return self._main.items()*n + def __mul__(self, n): return list(self._main.items())*n __rmul__ = __mul__ - def __add__(self, other): return self._main.items() + other - def __radd__(self, other): return other + self._main.items() + def __add__(self, other): return list(self._main.items()) + other + def __radd__(self, other): return other + list(self._main.items()) def append(self, item): """Add an item to the end.""" @@ -1076,7 +1076,7 @@ def __imul__(self, n): raise TypeError('Can\'t multiply items in place') class Values(object): """ Custom object for accessing the values of an OrderedDict. - + Can be called like the normal ``OrderedDict.values`` method, but also supports indexing and sequence methods. """ @@ -1090,7 +1090,7 @@ def __call__(self): def __getitem__(self, index): """Fetch the value at position i.""" - if isinstance(index, types.SliceType): + if isinstance(index, slice): return [self._main[key] for key in self._main._sequence[index]] else: return self._main[self._main._sequence[index]] @@ -1098,15 +1098,15 @@ def __getitem__(self, index): def __setitem__(self, index, value): """ Set the value at position i to value. - + You can only do slice assignment to values if you supply a sequence of equal length to the slice you are replacing. """ - if isinstance(index, types.SliceType): + if isinstance(index, slice): keys = self._main._sequence[index] if len(keys) != len(value): raise ValueError('attempt to assign sequence of size %s ' - 'to slice of size %s' % (len(name), len(keys))) + 'to slice of size %s' % (len(value), len(keys))) # FIXME: efficiency? Would be better to calculate the indexes # directly from the slice object # NOTE: the new keys can collide with existing keys (or even @@ -1117,41 +1117,41 @@ def __setitem__(self, index, value): self._main[self._main._sequence[index]] = value ### following methods pinched from UserList and adapted ### - def __repr__(self): return repr(self._main.values()) + def __repr__(self): return repr(list(self._main.values())) # FIXME: do we need to check if we are comparing with another ``Values`` # object? (like the __cast method of UserList) - def __lt__(self, other): return self._main.values() < other - def __le__(self, other): return self._main.values() <= other - def __eq__(self, other): return self._main.values() == other - def __ne__(self, other): return self._main.values() != other - def __gt__(self, other): return self._main.values() > other - def __ge__(self, other): return self._main.values() >= other - def __cmp__(self, other): return cmp(self._main.values(), other) - - def __contains__(self, item): return item in self._main.values() + def __lt__(self, other): return list(self._main.values()) < other + def __le__(self, other): return list(self._main.values()) <= other + def __eq__(self, other): return list(self._main.values()) == other + def __ne__(self, other): return list(self._main.values()) != other + def __gt__(self, other): return list(self._main.values()) > other + def __ge__(self, other): return list(self._main.values()) >= other + # def __cmp__(self, other): return cmp(list(self._main.values()), other) + + def __contains__(self, item): return item in list(self._main.values()) def __len__(self): return len(self._main._sequence) # easier :-) - def __iter__(self): return self._main.itervalues() - def count(self, item): return self._main.values().count(item) - def index(self, item, *args): return self._main.values().index(item, *args) + def __iter__(self): return iter(self._main.values()) + def count(self, item): return list(self._main.values()).count(item) + def index(self, item, *args): return list(self._main.values()).index(item, *args) def reverse(self): """Reverse the values""" - vals = self._main.values() + vals = list(self._main.values()) vals.reverse() # FIXME: efficiency self[:] = vals def sort(self, *args, **kwds): """Sort the values.""" - vals = self._main.values() + vals = list(self._main.values()) vals.sort(*args, **kwds) self[:] = vals - def __mul__(self, n): return self._main.values()*n + def __mul__(self, n): return list(self._main.values())*n __rmul__ = __mul__ - def __add__(self, other): return self._main.values() + other - def __radd__(self, other): return other + self._main.values() + def __add__(self, other): return list(self._main.values()) + other + def __radd__(self, other): return other + list(self._main.values()) ## following methods not implemented for values ## def __delitem__(self, i): raise TypeError('Can\'t delete items from values') @@ -1167,12 +1167,12 @@ class SequenceOrderedDict(OrderedDict): """ Experimental version of OrderedDict that has a custom object for ``keys``, ``values``, and ``items``. - + These are callable sequence objects that work as methods, or can be manipulated directly as sequences. - + Test for ``keys``, ``items`` and ``values``. - + >>> d = SequenceOrderedDict(((1, 2), (2, 3), (3, 4))) >>> d SequenceOrderedDict([(1, 2), (2, 3), (3, 4)]) @@ -1292,7 +1292,7 @@ class SequenceOrderedDict(OrderedDict): >>> d.values = (1, 2, 3) >>> d SequenceOrderedDict([(1, 1), (2, 2), (3, 3)]) - + >>> d = SequenceOrderedDict(((1, 2), (2, 3), (3, 4))) >>> d SequenceOrderedDict([(1, 2), (2, 3), (3, 4)]) @@ -1396,6 +1396,3 @@ def __setattr__(self, name, value): 'INTP_VER': INTP_VER, }) doctest.testmod(m, globs=globs) - - - diff --git a/pmx/options.py b/pmx/options.py index b2578ce1..404f0a28 100644 --- a/pmx/options.py +++ b/pmx/options.py @@ -85,7 +85,7 @@ def __init__(self, flag, otype, default, desc): self.parsed_opts = [] def __error(self, arg): - print >>sys.stderr,"Error: Option \"%s\" (%s) is not compatible with argument ->" % (self.flag, self.type), arg + print("Error: Option \"%s\" (%s) is not compatible with argument ->" % (self.flag, self.type), arg, file=sys.stderr) sys.exit(1) def __get_arg( self, arg): @@ -302,7 +302,7 @@ def __init__(self, cmdline, options = [], fileoptions = [], program_desc = [] , self.__make_option_dic() if self.opt['-h'].value == True: self.__print_program_descr() - print self + print(self) if self.opt['-h'].value == True: sys.exit(0) self.__check_for_unparsed_args() @@ -311,12 +311,12 @@ def __init__(self, cmdline, options = [], fileoptions = [], program_desc = [] , def __print_program_descr(self): - print - print 'HELP TEXT for "%s"' % (self.prog_name) - print '---------------------------------------------------------------------------------------------------------\n' + print() + print('HELP TEXT for "%s"' % (self.prog_name)) + print('---------------------------------------------------------------------------------------------------------\n') for line in self.program_desc: - print line.rstrip() + print(line.rstrip()) def __make_option_dic(self ): for opt in self.options+self.fileoptions: @@ -340,7 +340,7 @@ def __consistency_check( self ): olist = [] for opt in self.options+self.fileoptions: if opt.flag in olist: - print >>sys.stderr, "Error: Option flag \"%s\" defined multiple times" % opt.flag + print("Error: Option flag \"%s\" defined multiple times" % opt.flag, file=sys.stderr) sys.exit(1) olist.append( opt.flag ) @@ -387,14 +387,14 @@ def __check_flags(self): for flag in self.flag_list: n = self.flag_list.count( flag ) if n != 1: - print >>sys.stderr,"Error: Flag \"%s\" appears %d times in commandline" %(flag, n) + print("Error: Flag \"%s\" appears %d times in commandline" %(flag, n), file=sys.stderr) sys.exit(1) def __check_for_unparsed_args(self): error_occured = False for i, arg in enumerate(self.cmdline): if i not in self.parsed_opts: - print >>sys.stderr,"Error: Unknown argument \"%s\" in commandline" %(arg) + print("Error: Unknown argument \"%s\" in commandline" %(arg), file=sys.stderr) error_occured = True if error_occured: sys.exit(1) @@ -406,7 +406,7 @@ def __check_if_files_exist( self ): if o.mode[0]=='r': for f in o.filenames: if not os.path.isfile(f): - print >>sys.stderr, "Error: File \"%s\" does not exist!" % f + print("Error: File \"%s\" does not exist!" % f, file=sys.stderr) error_occured = True if error_occured: sys.exit(1) @@ -436,5 +436,5 @@ def __check_if_files_exist( self ): cmdl = Commandline( sys.argv, options = options, fileoptions = files, program_desc = help_text, check_for_existing_files = False ) - print cmdl['-pdb'] - print cmdl['-pdb2'] + print(cmdl['-pdb']) + print(cmdl['-pdb2']) diff --git a/pmx/parser.py b/pmx/parser.py index 8aebb5ba..a2affd7c 100644 --- a/pmx/parser.py +++ b/pmx/parser.py @@ -45,7 +45,7 @@ """ import sys -from odict import * +from .odict import * class ParserError(Exception): def __init__(self, s): @@ -84,7 +84,7 @@ def __parse_error(msg, line): s+= "\nTrouble is here -> %s" % line raise ParserError(s) ## print >>sys.stderr, "pmx_Error_> %s" % msg -## print >>sys.stderr, "pmx_Error_> Trouble is here -> %s" % line +## print >>sys.stderr, "pmx_Error_> Trouble is here -> %s" % line ## sys.exit(1) def __parse_entry(entr, tp): @@ -93,16 +93,16 @@ def __parse_entry(entr, tp): new = entr elif tp == 'i': try: - new = int(entr) + new = int(entr) except: __parse_error("Integer conversion failed", entr) elif tp == 'f': try: - new = float(entr) + new = float(entr) except: __parse_error("Float conversion failed", entr) return new - + def parseList(format_string, lst, ignore_missing = False): ret = [] @@ -117,7 +117,7 @@ def parseList(format_string, lst, ignore_missing = False): new_list.append( __parse_entry( entr[i], tp ) ) ret.append( new_list ) return ret - + def read_and_format(filename, format_string, comment = '#', ignore_missing = False): l = open(filename).readlines() @@ -158,9 +158,6 @@ def read_xvg( fn, style='xy'): if style == 'list': return res else: - x = map(lambda a: a[0], res) - y = map(lambda a: a[1], res) + x = [a[0] for a in res] + y = [a[1] for a in res] return x, y - - - diff --git a/pmx/rotamer.py b/pmx/rotamer.py index f90c051b..09bc9066 100644 --- a/pmx/rotamer.py +++ b/pmx/rotamer.py @@ -31,11 +31,11 @@ This file contains stuff to deal with the Dunbrack rotamer library""" import os, sys -from library import pmx_data_file, _aacids_dic +from .library import pmx_data_file, _aacids_dic -import molecule -import cPickle -from geometry import * +from . import molecule +import pickle +from .geometry import * _aa_chi = { 'CYS' : @@ -46,7 +46,7 @@ 2: [('CA' , 'CB' , 'CG' , 'OD1'), ['OD1','OD2','HD2']]}, 'GLU' : { 1: [('N' , 'CA' , 'CB' , 'CG' ),['1HB','2HB','CG','1HG','2HG','CD','OE1','OE2','HE2']], - 2: [('CA' , 'CB' , 'CG' , 'CD' ),['1HG','2HG','CD','OE1','OE2','HE2']], + 2: [('CA' , 'CB' , 'CG' , 'CD' ),['1HG','2HG','CD','OE1','OE2','HE2']], 3: [('CB' , 'CG' , 'CD' , 'OE1'),['OE1','OE2','HE2']] }, 'PHE' : { 1: [('N' , 'CA' , 'CB' , 'CG' ),['1HB', '2HB', 'CG' ,'CD1', 'HD1', 'CD2', 'HD2', 'CE1', 'HE1', 'CE2', 'HE2', 'CZ', 'HZ']], @@ -65,8 +65,8 @@ 2: [('CA' , 'CB' , 'CG' , 'ND1'),['CD2', 'ND1', 'HD2', 'HD1', 'NE2', 'CE1', 'HE2', 'HE1']] }, 'ILE' : { 1: [('N' , 'CA' , 'CB' , 'CG1'),['HB','CG1','1HG1','2HG1','CG2','1HG2','2HG2','3HG2','CD1','1HD1','2HD1','3HD1']], -# 2: [('CA' , 'CB' , 'CG1', 'CD1'),['1HG1','1HG2','CG2','1HG2','2HG2','3HG2','CD1','1HD1','2HD1','3HD1']] }, - 2: [('CA' , 'CB' , 'CG1', 'CD1'),['1HG1','2HG1','CD1','1HD1','2HD1','3HD1']] }, +# 2: [('CA' , 'CB' , 'CG1', 'CD1'),['1HG1','1HG2','CG2','1HG2','2HG2','3HG2','CD1','1HD1','2HD1','3HD1']] }, + 2: [('CA' , 'CB' , 'CG1', 'CD1'),['1HG1','2HG1','CD1','1HD1','2HD1','3HD1']] }, 'LYS' : { 1: [('N' , 'CA' , 'CB' ,'CG' ),['1HB','2HB','CG','1HG','2HG','CD','1HD','2HD','CE','1HE','2HE','NZ','1HZ','2HZ','3HZ']], 2: [('CA' , 'CB' , 'CG' ,'CD' ),['1HG','2HG','CD','1HD','2HD','CE','1HE','2HE','NZ','1HZ','2HZ','3HZ']], @@ -79,7 +79,7 @@ 4: [('CG' , 'CD' , 'CE' ,'NZ' ),['1HE','2HE','NZ','1HZ','2HZ']] }, 'LEU' : { 1: [('N' , 'CA' , 'CB' , 'CG' ),['1HB','2HB','CG', 'HG','CD1','1HD1','2HD1','3HD1','CD2','1HD2','2HD2','3HD2']], - 2: [('CA' , 'CB' , 'CG' , 'CD1'), ['HG','CD1','1HD1','2HD1','3HD1','CD2','1HD2','2HD2','3HD2']]}, + 2: [('CA' , 'CB' , 'CG' , 'CD1'), ['HG','CD1','1HD1','2HD1','3HD1','CD2','1HD2','2HD2','3HD2']]}, 'MET' : { 1: [('N' , 'CA' , 'CB' ,'CG' ),['1HB', '2HB', 'CG', '1HG', '2HG', 'SD', 'CE', '1HE', '2HE', '3HE']], 2: [('CA' , 'CB' , 'CG' ,'SD' ),['1HG', '2HG', 'SD', 'CE', '1HE', '2HE', '3HE']], @@ -89,7 +89,7 @@ 2: [('CA' , 'CB' , 'CG' , 'OD1'), ['OD1','ND2','1HD2','2HD2']]}, 'PRO' : { 1: [('N' , 'CA' , 'CB' , 'CG' ),[]], - 2: [('CA' , 'CB' , 'CG' , 'CD' ), []]}, + 2: [('CA' , 'CB' , 'CG' , 'CD' ), []]}, 'GLN' : { 1: [('N' , 'CA' , 'CB' , 'CG' ),['1HB','2HB','CG','1HG','2HG','CD','OE1','NE2','1HE2','2HE2']], 2: [('CA' , 'CB' , 'CG' , 'CD' ), ['1HG','2HG','CD','OE1','NE2','1HE2','2HE2']], @@ -129,19 +129,19 @@ def make_bbdep(min_val = .01): chi4 = float(entr[12]) key = (round(phi,0),round(psi,0)) if freq >= min_val: - if dic.has_key(resn): - if dic[resn].has_key(key): + if resn in dic: + if key in dic[resn]: dic[resn][key].append([freq, chi1, chi2, chi3, chi4]) else: dic[resn][key] = [[freq, chi1, chi2, chi3, chi4]] else: dic[resn] = {key:[[freq, chi1, chi2, chi3, chi4]]} - for key, val in dic.items(): - for bb, lst in val.items(): + for key, val in list(dic.items()): + for bb, lst in list(val.items()): lst.sort(lambda a,b: cmp(float(a[0]),float(b[0]))) lst.reverse() fp = open('bbdep.pkl','w') - cPickle.dump(dic,fp) + pickle.dump(dic,fp) @@ -168,7 +168,7 @@ def real_resname(r): 'HSD':'HIS','HISH':'HIS','HISD':'HIS','ASH':'ASP','ASPP':'ASP','ASPH':'ASP', 'GLH':'GLU','GLUH':'GLU','GLUP':'GLU', } - if dic.has_key(r): return dic[r] + if r in dic: return dic[r] else: return r def get_rotamers(bbdep, resname, phi, psi, residue = False, hydrogens = True, full = False): @@ -237,7 +237,7 @@ def select_best_rotamer(model, rotamers): # print 'Checking %d rotamers....' % len(rotamers) for i, r in enumerate(rotamers): score = check_overlaps(model, r, nb_list) - print i, score + print(i, score) if score < .2: return r if score < min_score: @@ -255,6 +255,3 @@ def mutate( residue, new_aa, bbdep): rotamers = get_rotamers( bbdep, new_aa, phi, psi, residue=residue, full = True, hydrogens = False) new_r = select_best_rotamer(m, rotamers) m.replace_residue( residue, new_r ) - - - diff --git a/pmx/scripts/analyze_dhdl.py b/pmx/scripts/analyze_dhdl.py index deeeb894..006be096 100755 --- a/pmx/scripts/analyze_dhdl.py +++ b/pmx/scripts/analyze_dhdl.py @@ -29,7 +29,7 @@ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # ---------------------------------------------------------------------- -from __future__ import print_function, division + from pmx.parser import read_and_format from pmx.estimators import Jarz, JarzGauss, Crooks, BAR, data2gauss, ks_norm_test import sys @@ -40,7 +40,7 @@ from scipy.integrate import simps import pickle import argparse -from cli import check_unknown_cmd +from .cli import check_unknown_cmd # Constants kb = 0.00831447215 # kJ/(K*mol) @@ -61,7 +61,7 @@ def gauss_func(A, mean, dev, x): # Files Parsing # ------------- def _longest_dgdl_file( lst ): - '''Takes a list of dgdl.xvg files and returns the id (starting from 0) of + '''Takes a list of dgdl.xvg files and returns the id (starting from 0) of of the longest file. Parameters @@ -174,7 +174,7 @@ def integrate_dgdl(fn, ndata=-1, lambda0=0, invert_values=False): lines = [l for l in lines if l[0] not in '#@&'] try: - r = map(lambda x: float(x.split()[1]), lines) + r = [float(x.split()[1]) for x in lines] except: r = "incomplete_file" ndata = 1 @@ -240,7 +240,7 @@ def _dump_integ_file(outfn, f_lst, w_lst): def _data_from_file(fn): data = read_and_format(fn, 'sf') - return map(lambda a: a[1], data) + return [a[1] for a in data] # ------------------ @@ -308,9 +308,9 @@ def smooth(x, window_len=11, window='hanning'): x1 = 0 x2 = 0 if 'A' in statesProvided: - x1 = range(len(wf)) + x1 = list(range(len(wf))) if 'B' in statesProvided: - x2 = range(len(wr)) + x2 = list(range(len(wr))) if x1 > x2: x = x1 else: @@ -320,7 +320,7 @@ def smooth(x, window_len=11, window='hanning'): if 'B' in statesProvided: mb, devb, Ab = data2gauss(wr) - if 'AB' in statesProvided: + if 'AB' in statesProvided: mini = min(wf+wr) maxi = max(wf+wr) sm1 = smooth(np.array(wf)) @@ -349,7 +349,7 @@ def smooth(x, window_len=11, window='hanning'): plt.grid(lw=2) plt.xlim(0, x[-1]+1) xl = plt.gca() - for val in xl.spines.values(): + for val in list(xl.spines.values()): val.set_lw(2) plt.subplot(1, 2, 2) plt.hist(wf, bins=nbins, orientation='horizontal', facecolor='green', @@ -392,7 +392,7 @@ def smooth(x, window_len=11, window='hanning'): plt.xticks([]) plt.yticks([]) xl = plt.gca() - for val in xl.spines.values(): + for val in list(xl.spines.values()): val.set_lw(2) plt.subplots_adjust(wspace=0.0, hspace=0.1) plt.savefig(fname, dpi=dpi) @@ -660,13 +660,13 @@ def main(args): if (args.filesAB is None) and (args.filesBA is None): exit('Need to provide dhdl.xvg files or integrated work values') elif args.filesAB is None: - statesProvided = 'B' - _tee(out, 'Only one directional Jarzynski estimator will be used') - filesBA = natural_sort(args.filesBA) - elif args.filesBA is None: - statesProvided = 'A' - _tee(out, 'Only one directional Jarzynski estimator will be used') - filesAB = natural_sort(args.filesAB) + statesProvided = 'B' + _tee(out, 'Only one directional Jarzynski estimator will be used') + filesBA = natural_sort(args.filesBA) + elif args.filesBA is None: + statesProvided = 'A' + _tee(out, 'Only one directional Jarzynski estimator will be used') + filesAB = natural_sort(args.filesAB) else: filesAB = natural_sort(args.filesAB) filesBA = natural_sort(args.filesBA) @@ -937,7 +937,7 @@ def main(args): p=prec, u=units)) if nblocks > 1: - if 'A' in statesProvided: + if 'A' in statesProvided: _tee(out, ' JARZ: Std Err Forward (blocks) = {e:8.{p}f} {u}'.format(e=jarz.err_blocks_for*unit_fact, p=prec, u=units)) if 'B' in statesProvided: @@ -953,29 +953,29 @@ def main(args): if args.pickle: pickle.dump(jarzGauss, open("jarz_gauss_results.pkl", "wb")) - if 'A' in statesProvided: + if 'A' in statesProvided: _tee(out, ' JARZ_Gauss: dG Forward = {dg:8.{p}f} {u}'.format(dg=jarzGauss.dg_for*unit_fact, p=prec, u=units)) - if 'B' in statesProvided: + if 'B' in statesProvided: _tee(out, ' JARZ_Gauss: dG Reverse = {dg:8.{p}f} {u}'.format(dg=jarzGauss.dg_rev*unit_fact, p=prec, u=units)) - if 'AB' in statesProvided: + if 'AB' in statesProvided: _tee(out, ' JARZ_Gauss: dG Mean = {dg:8.{p}f} {u}'.format(dg=(jarzGauss.dg_for+jarzGauss.dg_rev)/2.0*unit_fact, p=prec, u=units)) - if 'A' in statesProvided: + if 'A' in statesProvided: _tee(out, ' JARZ_Gauss: Std Err (analytical) Forward = {dg:8.{p}f} {u}'.format(dg=jarzGauss.err_for*unit_fact, p=prec, u=units)) - if 'B' in statesProvided: + if 'B' in statesProvided: _tee(out, ' JARZ_Gauss: Std Err (analytical) Reverse = {dg:8.{p}f} {u}'.format(dg=jarzGauss.err_rev*unit_fact, p=prec, u=units)) if nboots > 0: - if 'A' in statesProvided: + if 'A' in statesProvided: _tee(out, ' JARZ_Gauss: Std Err Forward (bootstrap) = {e:8.{p}f} {u}'.format(e=jarzGauss.err_boot_for*unit_fact, p=prec, u=units)) - if 'B' in statesProvided: + if 'B' in statesProvided: _tee(out, ' JARZ_Gauss: Std Err Reverse (bootstrap) = {e:8.{p}f} {u}'.format(e=jarzGauss.err_boot_rev*unit_fact,p=prec, u=units)) if nblocks > 1: - if 'A' in statesProvided: + if 'A' in statesProvided: _tee(out, ' JARZ_Gauss: Std Err Forward (blocks) = {e:8.{p}f} {u}'.format(e=jarzGauss.err_blocks_for*unit_fact,p=prec, u=units)) if 'B' in statesProvided: _tee(out, ' JARZ_Gauss: Std Err Reverse (blocks) = {e:8.{p}f} {u}'.format(e=jarzGauss.err_blocks_rev*unit_fact,p=prec, u=units)) diff --git a/pmx/scripts/cli.py b/pmx/scripts/cli.py index 6ef33851..7ef0a1a4 100755 --- a/pmx/scripts/cli.py +++ b/pmx/scripts/cli.py @@ -37,19 +37,19 @@ def __init__(self): getattr(self, args.command)() def mutate(self): - import mutate + from . import mutate mutate.entry_point() def gentop(self): - import generate_hybrid_topology + from . import generate_hybrid_topology generate_hybrid_topology.entry_point() def analyse(self): - import analyze_dhdl + from . import analyze_dhdl analyze_dhdl.entry_point() def gmxlib(self): - import set_gmxlib + from . import set_gmxlib set_gmxlib.entry_point() @@ -62,8 +62,8 @@ def check_unknown_cmd(unknowns): for cmd in unknowns: if cmd not in expected: - print('Unknown command found in your command line: "{}". ' - 'This command will be ignored'.format(cmd)) + print(('Unknown command found in your command line: "{}". ' + 'This command will be ignored'.format(cmd))) def entry_point(): diff --git a/pmx/scripts/generate_hybrid_residue.py b/pmx/scripts/generate_hybrid_residue.py index 9e67ac73..810320c0 100755 --- a/pmx/scripts/generate_hybrid_residue.py +++ b/pmx/scripts/generate_hybrid_residue.py @@ -112,7 +112,7 @@ ('O1P','O1P'), ('O2P','O2P'), ] - + standard_rna_5term_pair_list = [ ('C1\'','C1\''), ('C2\'','C2\''), @@ -176,7 +176,7 @@ ('O1P','O1P'), ('O2P','O2P'), ] - + standard_dna_5term_pair_list = [ ('C1\'','C1\''), ('C2\'','C2\''), @@ -238,7 +238,7 @@ ('O1P','O1P'), ('O2P','O2P'), ] - + standard_dna_5term_pair_list_charmm = [ ('C1\'','C1\''), ('C2\'','C2\''), @@ -339,7 +339,7 @@ } res_with_rings = [ 'HIS','HID','HIE','HIP','HISE','HISH','HIS1','HISD','HSE','HSD','HSP', - 'PHE','TYR','TRP','PRO' ] + 'PHE','TYR','TRP','PRO' ] res_diff_Cb = [ 'THR', 'ALA', 'VAL', 'ILE' ] @@ -359,7 +359,7 @@ 'HISE':['HIS1','HISD','HISH'], 'HISH':['HIS1','HISD','HISE'] } - + mol_branch = { 'ILE':2, @@ -428,15 +428,15 @@ def dna_mutation_naming(aa1,aa2): rr_name = 'D'+aa1[-1]+aa2[-1] dict_key = aa1+'_'+aa2 - if dict_key in dna_names.keys(): - rr_name = dna_names[dict_key] + if dict_key in list(dna_names.keys()): + rr_name = dna_names[dict_key] return(rr_name) def rna_mutation_naming(aa1,aa2): rr_name = 'R'+aa1[-1]+aa2[-1] dict_key = aa1+'_'+aa2 - if dict_key in dna_names.keys(): - rr_name = dna_names[dict_key] + if dict_key in list(dna_names.keys()): + rr_name = dna_names[dict_key] return(rr_name) def max_rotation(dihedrals): @@ -450,7 +450,7 @@ def get_dihedrals(resname): return library._aa_dihedrals[resname] def set_dihedral(atoms,mol,phi): - print atoms[0].name,atoms[1].name,atoms[2].name + print(atoms[0].name,atoms[1].name,atoms[2].name) a1 = atoms[0] a2 = atoms[1] a3 = atoms[2] @@ -491,12 +491,12 @@ def do_fit(m1,dihed1,m2,dihed2): if dih2[-1] == chi and dih2[-2] == 1: diheds.append((dih,dih2)) for dih1, dih2 in diheds: -# for d in range(0,4): -# foo = dih2[d] -# if is_number(foo[-1]) and is_number(foo[-2]): -# dih2[d] = foo[-1] + foo[0] + foo[1] + foo[2] -# elif foo[0]=='H' and foo[1]=='B': -# dih2[d] = foo[-1] + foo[0] + foo[1] +# for d in range(0,4): +# foo = dih2[d] +# if is_number(foo[-1]) and is_number(foo[-2]): +# dih2[d] = foo[-1] + foo[0] + foo[1] + foo[2] +# elif foo[0]=='H' and foo[1]=='B': +# dih2[d] = foo[-1] + foo[0] + foo[1] # foo = dih1[d] # if is_number(foo[-1]) and is_number(foo[-2]): # dih1[d] = foo[-1] + foo[0] + foo[1] + foo[2] @@ -504,21 +504,21 @@ def do_fit(m1,dihed1,m2,dihed2): # dih1[d] = foo[-1] + foo[0] + foo[1] atoms1 = m1.fetchm(dih1) - print "fetching" + print("fetching") atoms2 = m2.fetchm(dih2) - print dih2 - print atoms2 + print(dih2) + print(atoms2) a1,a2,a3,a4 = atoms1 if (a2.name, a3.name) not in bonds: phi = a1.dihedral(a2,a3,a4) # print phi # print 'rot1', a1.name,a2.name,a3.name,a4.name - set_dihedral(atoms2,m2,phi) + set_dihedral(atoms2,m2,phi) # a1,a2,a3,a4 = atoms1 # print a1.dihedral(a2,a3,a4) op = open('check.pdb','w') for atom in m2.atoms: - print >>op, atom + print(atom, file=op) def tag(atom): @@ -527,30 +527,30 @@ def tag(atom): def align_sidechains(r1, r2): #MS: if you add new force field, check pmx/molecule.py, make sure res is - #MS: correctly set into get_real_resname + #MS: correctly set into get_real_resname for i in range(r1.nchi()): phi = r1.get_chi(i+1, degree = True) r2.set_chi(i+1,phi) def rename_atoms_dna(m): for atom in m.atoms: - aname = atom.name - if len(aname)==4: - if (aname[0].isdigit()==True) or (aname[0]=='\''): - first = aname[0] - rest = aname[1:] - new = rest+first - atom.name = new + aname = atom.name + if len(aname)==4: + if (aname[0].isdigit()==True) or (aname[0]=='\''): + first = aname[0] + rest = aname[1:] + new = rest+first + atom.name = new def rename_atoms_rna(m): for atom in m.atoms: - aname = atom.name - if len(aname)==4: - if (aname[0].isdigit()==True) or (aname[0]=='\''): - first = aname[0] - rest = aname[1:] - new = rest+first - atom.name = new + aname = atom.name + if len(aname)==4: + if (aname[0].isdigit()==True) or (aname[0]=='\''): + first = aname[0] + rest = aname[1:] + new = rest+first + atom.name = new def assign_rtp_entries( mol, rtp): entr = rtp[mol.resname] @@ -561,27 +561,27 @@ def assign_rtp_entries( mol, rtp): atom_type = atom_entry[1] atom_q = atom_entry[2] atom_cgnr = atom_entry[3] - print "foo ",atom_name + print("foo ",atom_name) atom = mol.fetch( atom_name )[0] atom.atomtype = atom_type atom.q = atom_q atom.cgnr = atom_cgnr # bonds for a1, a2 in entr['bonds']: - #MS charmm uses next residue in bonds (+), amber previous (-) - #MS also write rtp is affected now, since normally -C N is added - #MS charmm used C +N, problem is that you run into trouble on the - #MS termini - bmin=not '-' in a1 and not '-' in a2 - bplus=not '+' in a1 and not '+' in a2 + #MS charmm uses next residue in bonds (+), amber previous (-) + #MS also write rtp is affected now, since normally -C N is added + #MS charmm used C +N, problem is that you run into trouble on the + #MS termini + bmin=not '-' in a1 and not '-' in a2 + bplus=not '+' in a1 and not '+' in a2 if bmin and bplus: atom1, atom2 = mol.fetchm( [a1, a2] ) atom1.bonds.append( atom2 ) atom2.bonds.append( atom1 ) - else : - neigh.append([a1,a2]) + else : + neigh.append([a1,a2]) return neigh - + def assign_branch(mol): for atom in mol.atoms: @@ -591,7 +591,7 @@ def assign_branch(mol): atom.branch = 1 else: atom.branch = 2 - + def get_atoms_by_order(mol,order): res = [] for atom in mol.atoms: @@ -606,7 +606,7 @@ def get_atoms_by_order_and_branch( mol, order, branch, merged_atoms ): if atom.branch in [0,branch] or atom.branch < mol_branch[mol.real_resname] + 1: res.append(atom) return res - + def last_atom_is_morphed( atom, merged_list ): for at in atom.bonds: @@ -635,14 +635,14 @@ def cmp_mol2_types( type1, type2 ): return False # print type1, type2, '????' # sys.exit(1) - - + + def find_closest_atom( atom1, atom_list, merged_atoms, bH2heavy=True ): min_d = 0.55 idx = 99 for i, atom in enumerate(atom_list): if atom not in merged_atoms: - if bH2heavy==False: + if bH2heavy==False: ### check for H2heavy morphe ### if(atom1.atomtype.startswith('H') and (not atom.atomtype.startswith('H')) ): continue @@ -650,7 +650,7 @@ def find_closest_atom( atom1, atom_list, merged_atoms, bH2heavy=True ): continue d = atom1 - atom - print "%s %s %f" %(atom1.name,atom.name,d) + print("%s %s %f" %(atom1.name,atom.name,d)) if d < min_d: min_d = d idx = i @@ -660,24 +660,24 @@ def find_closest_atom( atom1, atom_list, merged_atoms, bH2heavy=True ): def make_predefined_pairs( mol1, mol2, pair_list ): # make main chain + cb pairs - print 'Making atom pairs.........' + print('Making atom pairs.........') atom_pairs = [] merged_atoms1 = [] merged_atoms2 = [] for name1, name2 in pair_list: - try: - at1 = mol1.fetch( name1 )[0] - except IndexError: - at1 = mol1.fetch( reformat_atom_name(name1) )[0] + try: + at1 = mol1.fetch( name1 )[0] + except IndexError: + at1 = mol1.fetch( reformat_atom_name(name1) )[0] try: at2 = mol2.fetch( name2 )[0] except IndexError: at2 = mol2.fetch( reformat_atom_name(name2) )[0] - at1.name = reformat_atom_name(name1) + at1.name = reformat_atom_name(name1) at2.name = reformat_atom_name(name2) -# print name1,name2 -# at1 = mol1.fetch( reformat_atom_name(name1) )[0] -# at2 = mol2.fetch( name2 )[0] +# print name1,name2 +# at1 = mol1.fetch( reformat_atom_name(name1) )[0] +# at2 = mol2.fetch( name2 )[0] at1.atomtypeB = at2.atomtype at1.qB = at2.q at1.mB = at2.m @@ -687,11 +687,11 @@ def make_predefined_pairs( mol1, mol2, pair_list ): atom_pairs.append( [at1, at2] ) ## if atom.atomtypeB.startswith('DUM'): ## atom.nameB = atom.name+'.gone' - dummies = mol2.fetch_atoms( map( lambda a: a.name, merged_atoms1), inv = True ) + dummies = mol2.fetch_atoms( [a.name for a in merged_atoms1], inv = True ) return atom_pairs, dummies def merge_by_names( mol1, mol2 ): - print 'Making atom pairs.........MERGE BY NAMES......' + print('Making atom pairs.........MERGE BY NAMES......') atom_pairs = [] merged_atoms1 = [] merged_atoms2 = [] @@ -709,26 +709,26 @@ def merge_by_names( mol1, mol2 ): pass ## if atom.atomtypeB.startswith('DUM'): ## atom.nameB = atom.name+'.gone' - dummies = mol2.fetch_atoms( map( lambda a: a.name, merged_atoms1), inv = True ) + dummies = mol2.fetch_atoms( [a.name for a in merged_atoms1], inv = True ) return atom_pairs, dummies - + def make_pairs( mol1, mol2,bCharmm, bH2heavy=True, bDNA=False, bRNA=False ): # make main chain + cb pairs - print 'Making atom pairs.........' + print('Making atom pairs.........') mol1.batoms = [] merged_atoms1 = [] merged_atoms2 = [] atom_pairs = [] if bDNA or bRNA: - mc_list = [] + mc_list = [] elif bCharmm : mc_list = ['N','CA','C','O','HN','HA','CB'] - gly_mc_list = ['N','CA','C','O','HN','1HA','2HA'] + gly_mc_list = ['N','CA','C','O','HN','1HA','2HA'] else : mc_list = ['N','CA','C','O','H','HA','CB'] - gly_mc_list = ['N','CA','C','O','H','1HA','2HA'] + gly_mc_list = ['N','CA','C','O','H','1HA','2HA'] if mol1.resname == 'GLY': atoms1 = mol1.fetchm( gly_mc_list ) @@ -751,30 +751,30 @@ def make_pairs( mol1, mol2,bCharmm, bH2heavy=True, bDNA=False, bRNA=False ): # now go for the rest of the side chain if bDNA or bRNA: - # identify atom morphes by distances - atoms1 = mol1.atoms - atoms2 = mol2.atoms + # identify atom morphes by distances + atoms1 = mol1.atoms + atoms2 = mol2.atoms for at1 in atoms1: - print '-- Checking atom...', at1.name - aa, d = find_closest_atom( at1, atoms2, merged_atoms2, bH2heavy ) - if aa: + print('-- Checking atom...', at1.name) + aa, d = find_closest_atom( at1, atoms2, merged_atoms2, bH2heavy ) + if aa: merged_atoms2.append( aa ) merged_atoms1.append( at1 ) atom_pairs.append( [ at1, aa] ) - print "here ",at1.name, aa.name + print("here ",at1.name, aa.name) else: for k in [1,2]: - print '-- Searching branch', k + print('-- Searching branch', k) done_branch = False for i in range( 2, 8 ): if done_branch: break - print '-- Searching order', i + print('-- Searching order', i) atoms1 = get_atoms_by_order_and_branch( mol1, i, k, merged_atoms1 ) atoms2 = get_atoms_by_order_and_branch( mol2, i, k, merged_atoms2 ) for at1 in atoms1: if last_atom_is_morphed( at1, merged_atoms1 ): - print '-- Checking atom...', at1.name + print('-- Checking atom...', at1.name) candidates = [] for at2 in atoms2: #if cmp_mol2_types( at1.atype, at2.atype): @@ -784,15 +784,15 @@ def make_pairs( mol1, mol2,bCharmm, bH2heavy=True, bDNA=False, bRNA=False ): merged_atoms2.append( aa ) merged_atoms1.append( at1 ) atom_pairs.append( [ at1, aa] ) - print '--> Define atom pair: ', tag(at1), '- >', tag(aa), '(d = %4.2f A)' % d + print('--> Define atom pair: ', tag(at1), '- >', tag(aa), '(d = %4.2f A)' % d) else: - print 'No partner found for atom ', at1.name + print('No partner found for atom ', at1.name) ## print '-- done branch', k ## done_branch = True ## break # done with this branch for at1, at2 in atom_pairs: - print at1,at2 + print(at1,at2) at1.atomtypeB = at2.atomtype at1.qB = at2.q at1.mB = at2.m @@ -814,7 +814,7 @@ def check_double_atom_names( r ): alist = r.fetch_atoms( atom.name ) if len(alist) != 1: alist = r.fetch_atoms( atom.name[:-1], wildcard = True ) - print 'Renaming atoms (%s)' % alist[0].name[:-1] + print('Renaming atoms (%s)' % alist[0].name[:-1]) start = 1 for atom in alist: atom.name = atom.name[:3]+str(start) @@ -823,7 +823,7 @@ def check_double_atom_names( r ): return True def merge_molecules( r1, dummies ): - + for atom in dummies: new_atom = atom.copy() new_atom.atomtypeB = new_atom.atomtype @@ -837,7 +837,7 @@ def merge_molecules( r1, dummies ): new_atom.name = 'D'+new_atom.name[:3] if new_atom.name[1].isdigit(): new_atom.name = new_atom.name[0]+new_atom.name[2:]+new_atom.name[1] - + else: new_atom.name = 'D'+atom.name r1.append( new_atom ) @@ -850,7 +850,7 @@ def make_bstate_dummies(r1): atom.atomtypeB = 'DUM_'+atom.atomtype atom.qB = 0 atom.mB = atom.m - + def make_transition_dics( atom_pairs, r1 ): abdic = {} badic = {} @@ -872,16 +872,16 @@ def find_atom_by_nameB( r, name ): def update_bond_lists(r1, badic): - print 'Updating bond lists...........' + print('Updating bond lists...........') for atom in r1.atoms: if atom.name[0] == 'D': - print 'atom', atom.name - print ' | ' + print('atom', atom.name) + print(' | ') new_list = [] while atom.bonds: at = atom.bonds.pop(0) - print atom.name, '->', at.name - if badic.has_key(at.name): + print(atom.name, '->', at.name) + if at.name in badic: aa = r1.fetch( badic[at.name] )[0] new_list.append( aa ) else: @@ -889,72 +889,72 @@ def update_bond_lists(r1, badic): if aa is not None: new_list.append(aa) else: - print 'Atom not found', at.name, at.nameB + print('Atom not found', at.name, at.nameB) sys.exit(1) atom.bonds = new_list for at in atom.bonds: if atom not in at.bonds: at.bonds.append( atom ) - print '----bond--->', at.name - print + print('----bond--->', at.name) + print() def improp_entries_match( lst1, lst2 ): res = True for a1, a2 in zip(lst1, lst2): -# print "foo ",a1.name,a2.name +# print "foo ",a1.name,a2.name if a1.name != a2.name: res=False if( res==True ): - return res + return res res = True for a1, a2 in zip(lst1, list(reversed(lst2))): -# print "foo ",a1.name,a2.name +# print "foo ",a1.name,a2.name if a1.name != a2.name: res=False return res def generate_dihedral_entries( im1, im2, r, pairs ): - print 'Updating dihedrals...........' + print('Updating dihedrals...........') new_ii = [] done_i1 = [] done_i2 = [] # ILDN dihedrals for i1 in im1: - #print '%s %s %s %s %s' % (i1[0].name,i1[1].name,i1[2].name,i1[3].name,i1[4]) + #print '%s %s %s %s %s' % (i1[0].name,i1[1].name,i1[2].name,i1[3].name,i1[4]) for i2 in im2: if improp_entries_match(i1[:4], i2[:4]) and (i2 not in done_i2): im_new = i1[:4] - if i1[4] == '': - im_new.append( 'default-A' ) - else: - im_new.append( i1[4] ) - if i2[4] == '': - im_new.append( 'default-B' ) - else: - im_new.append( i2[4] ) + if i1[4] == '': + im_new.append( 'default-A' ) + else: + im_new.append( i1[4] ) + if i2[4] == '': + im_new.append( 'default-B' ) + else: + im_new.append( i2[4] ) done_i1.append( i1 ) done_i2.append( i2 ) new_ii.append( im_new ) - break + break for i1 in im1: if i1 not in done_i1: im_new = i1[:4] - if i1[4] == '': + if i1[4] == '': im_new.append( 'default-A' ) if( ('gone' in i1[0].nameB) or ('gone' in i1[1].nameB) or ('gone' in i1[2].nameB) or ('gone' in i1[3].nameB) ): im_new.append( 'default-A' ) else: im_new.append( 'un' ) else: - if ( ('gone' in i1[0].nameB) or ('gone' in i1[1].nameB) or ('gone' in i1[2].nameB) or ('gone' in i1[3].nameB) ): - im_new.append( i1[4] ) + if ( ('gone' in i1[0].nameB) or ('gone' in i1[1].nameB) or ('gone' in i1[2].nameB) or ('gone' in i1[3].nameB) ): im_new.append( i1[4] ) - else: im_new.append( i1[4] ) - if( 'torsion' in i1[4] ): #ildn - tors = copy.deepcopy(i1[4]) - tors = tors.replace('torsion','tors') + else: + im_new.append( i1[4] ) + if( 'torsion' in i1[4] ): #ildn + tors = copy.deepcopy(i1[4]) + tors = tors.replace('torsion','tors') foo = 'un' + tors im_new.append( foo ) - elif( 'dih_' in i1[4] ): #opls + elif( 'dih_' in i1[4] ): #opls foo = 'un' + i1[4] im_new.append( foo ) else: @@ -962,36 +962,36 @@ def generate_dihedral_entries( im1, im2, r, pairs ): new_ii.append( im_new ) for i2 in im2: if i2 not in done_i2: - im_new = i2[:4] - if i2[4] == '': + im_new = i2[:4] + if i2[4] == '': if( (i2[0].name.startswith('D')) or (i2[1].name.startswith('D')) or (i2[2].name.startswith('D')) or (i2[3].name.startswith('D')) ): im_new.append( 'default-B' ) else: im_new.append( 'un' ) - im_new.append( 'default-B' ) - else: + im_new.append( 'default-B' ) + else: if ( (i2[0].name.startswith('D')) or (i2[1].name.startswith('D')) or (i2[2].name.startswith('D')) or (i2[3].name.startswith('D')) ): im_new.append( i2[4] ) im_new.append( i2[4] ) else: - if( 'torsion' in i2[4] ): #ildn + if( 'torsion' in i2[4] ): #ildn tors = copy.deepcopy(i2[4]) tors = tors.replace('torsion','tors') - foo = 'un' + tors - im_new.append( foo ) + foo = 'un' + tors + im_new.append( foo ) elif( 'dih_' in i2[4] ): #opls foo = 'un' + i2[4] im_new.append( foo ) - else: - im_new.append( 'un' ) + else: + im_new.append( 'un' ) im_new.append( i2[4] ) new_ii.append( im_new ) - + return new_ii def generate_improp_entries( im1, im2, r ): - print 'Updating impropers...........' - + print('Updating impropers...........') + new_ii = [] done_i1 = [] done_i2 = [] @@ -999,37 +999,37 @@ def generate_improp_entries( im1, im2, r ): for i1 in im1: for i2 in im2: if improp_entries_match(i1[:4], i2[:4]): - print 'alus %s' % i1[4] + print('alus %s' % i1[4]) im_new = i1[:4] - if i1[4] == '': - im_new.append( 'default-A' ) - elif( i1[4] == '105.4' ): #star - im_new.append( 'default-star' ) - else: - im_new.append( i1[4] ) - if i2[4] == '': - im_new.append( 'default-B' ) + if i1[4] == '': + im_new.append( 'default-A' ) + elif( i1[4] == '105.4' ): #star + im_new.append( 'default-star' ) + else: + im_new.append( i1[4] ) + if i2[4] == '': + im_new.append( 'default-B' ) elif( i2[4] == '105.4' ): #star im_new.append( 'default-star' ) - else: - im_new.append( i2[4] ) + else: + im_new.append( i2[4] ) done_i1.append( i1 ) done_i2.append( i2 ) new_ii.append( im_new ) for i1 in im1: if i1 not in done_i1: - im_new = i1[:4] - if i1[4] == '': - im_new.append( 'default-A' ) - if( ('gone' in i1[0].nameB) or ('gone' in i1[1].nameB) or ('gone' in i1[2].nameB) or ('gone' in i1[3].nameB) ): - im_new.append( 'default-A' ) - else: - im_new.append( 'un' ) + im_new = i1[:4] + if i1[4] == '': + im_new.append( 'default-A' ) + if( ('gone' in i1[0].nameB) or ('gone' in i1[1].nameB) or ('gone' in i1[2].nameB) or ('gone' in i1[3].nameB) ): + im_new.append( 'default-A' ) + else: + im_new.append( 'un' ) elif( i1[4] == '105.4' ): #star im_new.append( 'default-star' ) im_new.append( 'un' ) - else: - im_new.append( i1[4] ) + else: + im_new.append( i1[4] ) if( ('gone' in i1[0].nameB) or ('gone' in i1[1].nameB) or ('gone' in i1[2].nameB) or ('gone' in i1[3].nameB) ): im_new.append( i1[4] ) else: @@ -1037,14 +1037,14 @@ def generate_improp_entries( im1, im2, r ): new_ii.append( im_new ) for i2 in im2: if i2 not in done_i2: - im_new = i2[:4] #[ find_atom_by_nameB(r, n) for n in i2[:4] ] + im_new = i2[:4] #[ find_atom_by_nameB(r, n) for n in i2[:4] ] # im_new.append( 'default-B' ) - if i2[4] == '': + if i2[4] == '': if( (i2[0].name.startswith('D')) or (i2[1].name.startswith('D')) or (i2[2].name.startswith('D')) or (i2[3].name.startswith('D')) ): im_new.append( 'default-B' ) else: im_new.append( 'un' ) - im_new.append( 'default-B' ) + im_new.append( 'default-B' ) elif( i2[4] == '105.4' ): #star im_new.append( 'un' ) im_new.append( 'default-star' ) @@ -1053,7 +1053,7 @@ def generate_improp_entries( im1, im2, r ): im_new.append( i2[4] ) else: im_new.append( 'un' ) - im_new.append( i2[4] ) + im_new.append( i2[4] ) new_ii.append( im_new ) ## for ii in new_ii: ## print '--->', ' '.join(ii) @@ -1061,46 +1061,46 @@ def generate_improp_entries( im1, im2, r ): return new_ii def write_rtp( fp, r, ii_list, dihi_list,neigh_bonds,cmap): - print >>fp,'\n[ %s ] ; %s -> %s\n' % (r.resname, r.resnA, r.resnB) - print >>fp,' [ atoms ]' + print('\n[ %s ] ; %s -> %s\n' % (r.resname, r.resnA, r.resnB), file=fp) + print(' [ atoms ]', file=fp) cgnr = 1 for atom in r.atoms: - print >>fp, "%6s %-15s %8.5f %d" % (atom.name, atom.atomtype, atom.q, cgnr) + print("%6s %-15s %8.5f %d" % (atom.name, atom.atomtype, atom.q, cgnr), file=fp) cgnr+=1 - print >>fp,'\n [ bonds ]' + print('\n [ bonds ]', file=fp) for atom in r.atoms: for at in atom.bonds: if atom.id < at.id: - print >>fp, "%6s %6s ; (%6s %6s)" % ( atom.name, at.name, atom.nameB, at.nameB ) + print("%6s %6s ; (%6s %6s)" % ( atom.name, at.name, atom.nameB, at.nameB ), file=fp) #MS here there will have to be a check for FF, since for charmm we need to add C N #MSsave those bonds with previous and next residue as a seperate entry for i in neigh_bonds : - print >>fp, "%6s %6s " % (i[0],i[1]) + print("%6s %6s " % (i[0],i[1]), file=fp) - print >>fp,'\n [ impropers ]' + print('\n [ impropers ]', file=fp) for ii in ii_list: if not ii[4].startswith('default'): - print >>fp, "%6s %6s %6s %6s %-25s" % ( ii[0].name, ii[1].name, ii[2].name, ii[3].name, ii[4]) + print("%6s %6s %6s %6s %-25s" % ( ii[0].name, ii[1].name, ii[2].name, ii[3].name, ii[4]), file=fp) else: - print >>fp, "%6s %6s %6s %6s " % ( ii[0].name, ii[1].name, ii[2].name, ii[3].name) + print("%6s %6s %6s %6s " % ( ii[0].name, ii[1].name, ii[2].name, ii[3].name), file=fp) - print >>fp,'\n [ dihedrals ]' + print('\n [ dihedrals ]', file=fp) for ii in dihi_list: if not ii[4].startswith('default'): - print >>fp, "%6s %6s %6s %6s %-25s" % ( ii[0].name, ii[1].name, ii[2].name, ii[3].name, ii[4]) + print("%6s %6s %6s %6s %-25s" % ( ii[0].name, ii[1].name, ii[2].name, ii[3].name, ii[4]), file=fp) else: - print >>fp, "%6s %6s %6s %6s " % ( ii[0].name, ii[1].name, ii[2].name, ii[3].name) + print("%6s %6s %6s %6s " % ( ii[0].name, ii[1].name, ii[2].name, ii[3].name), file=fp) if cmap : - print >>fp,'\n [ cmap ]' + print('\n [ cmap ]', file=fp) for i in cmap: - print >>fp, "%s " % (i) + print("%s " % (i), file=fp) def write_mtp( fp, r, ii_list, rotations, dihi_list ): - print >>fp,'\n[ %s ] ; %s -> %s\n' % (r.resname, r.resnA, r.resnB) - print >>fp,'\n [ morphes ]' + print('\n[ %s ] ; %s -> %s\n' % (r.resname, r.resnA, r.resnB), file=fp) + print('\n [ morphes ]', file=fp) for atom in r.atoms: - print >>fp, "%6s %10s -> %6s %10s" % ( atom.name, atom.atomtype, atom.nameB, atom.atomtypeB ) - print >>fp,'\n [ atoms ]' + print("%6s %10s -> %6s %10s" % ( atom.name, atom.atomtype, atom.nameB, atom.atomtypeB ), file=fp) + print('\n [ atoms ]', file=fp) cgnr = 1 for atom in r.atoms: ext = ' ; ' @@ -1109,51 +1109,51 @@ def write_mtp( fp, r, ii_list, rotations, dihi_list ): if atom.q != atom.qB: ext+= '| charge != ' else: ext+= '| charge == ' - print >>fp ,"%8s %10s %10.6f %6d %10.6f %10s %10.6f %10.6f %-10s" % \ - ( atom.name, atom.atomtype, atom.q, cgnr, atom.m, atom.atomtypeB, atom.qB, atom.mB, ext ) - print >>fp,'\n [ coords ]' + print("%8s %10s %10.6f %6d %10.6f %10s %10.6f %10.6f %-10s" % \ + ( atom.name, atom.atomtype, atom.q, cgnr, atom.m, atom.atomtypeB, atom.qB, atom.mB, ext ), file=fp) + print('\n [ coords ]', file=fp) for atom in r.atoms: - print >>fp,"%8.3f %8.3f %8.3f" % (atom.x[0], atom.x[1], atom.x[2]) + print("%8.3f %8.3f %8.3f" % (atom.x[0], atom.x[1], atom.x[2]), file=fp) - print >>fp,'\n [ impropers ]' + print('\n [ impropers ]', file=fp) for ii in ii_list: - print >>fp," %6s %6s %6s %6s %-25s %-25s " % \ - ( ii[0].name, ii[1].name, ii[2].name, ii[3].name, ii[4], ii[5] ) - print + print(" %6s %6s %6s %6s %-25s %-25s " % \ + ( ii[0].name, ii[1].name, ii[2].name, ii[3].name, ii[4], ii[5] ), file=fp) + print() - print >>fp,'\n [ dihedrals ]' + print('\n [ dihedrals ]', file=fp) for ii in dihi_list: - print >>fp," %6s %6s %6s %6s %-25s %-25s " % \ - ( ii[0].name, ii[1].name, ii[2].name, ii[3].name, ii[4], ii[5] ) - print + print(" %6s %6s %6s %6s %-25s %-25s " % \ + ( ii[0].name, ii[1].name, ii[2].name, ii[3].name, ii[4], ii[5] ), file=fp) + print() if rotations: - print >>fp, '\n [ rotations ]' + print('\n [ rotations ]', file=fp) for rot in rotations: - print >>fp, ' %s-%s %s' % (rot[0].name, rot[1].name, ' '.join( map(lambda a: a.name, rot[2:]) ) ) - print >>fp + print(' %s-%s %s' % (rot[0].name, rot[1].name, ' '.join( [a.name for a in rot[2:]] ) ), file=fp) + print(file=fp) def primitive_check( atom, rot_atom ): if atom in rot_atom.bonds: return True else: return False - + def find_higher_atoms( rot_atom, r, order, branch ): res = [] for atom in r.atoms: - print "1level: %s %s %s" % (atom.name,atom.order,atom.branch) - if( ('gone' in rot_atom.nameB) and atom.name.startswith('D') ): - continue + print("1level: %s %s %s" % (atom.name,atom.order,atom.branch)) + if( ('gone' in rot_atom.nameB) and atom.name.startswith('D') ): + continue # if atom.order >= order and \ # (atom.branch == branch or branch == 0): if atom.order >= order: - print "2level: %s %s %s" % (atom.name,atom.order,atom.branch) + print("2level: %s %s %s" % (atom.name,atom.order,atom.branch)) if atom.order == rot_atom.order+1: - print "3level: %s %s %s" % (atom.name,atom.order,atom.branch) + print("3level: %s %s %s" % (atom.name,atom.order,atom.branch)) if primitive_check( atom, rot_atom ): - print "4level: %s %s %s" % (atom.name,atom.order,atom.branch) + print("4level: %s %s %s" % (atom.name,atom.order,atom.branch)) res.append( atom ) else: - res.append( atom ) + res.append( atom ) return res @@ -1183,15 +1183,15 @@ def make_rotations( r, resn1_dih, resn2_dih ): # rot_atoms = [ dih_atoms[1], dih_atoms[2] ] # atom1 = rot_atoms[0] # atom2 = rot_atoms[1] - atom1 = r.fetchm( chi )[1] - atom2 = r.fetchm( chi )[2] + atom1 = r.fetchm( chi )[1] + atom2 = r.fetchm( chi )[2] rot_list.append( atom1 ) rot_list.append( atom2 ) oo = atom2.order bb = atom2.branch - print "AAAAAAAAA %s %s %s" %(atom2,oo+1,bb) + print("AAAAAAAAA %s %s %s" %(atom2,oo+1,bb)) atoms_to_rotate = [] - atoms_to_rotate = find_higher_atoms(atom2, r, oo+1, bb ) + atoms_to_rotate = find_higher_atoms(atom2, r, oo+1, bb ) for atom in atoms_to_rotate: rot_list.append( atom ) # print atom.name @@ -1206,23 +1206,23 @@ def parse_ffnonbonded_charmm(ffnonbonded,f): bAdd=True for line in lines: if line.strip()=='#ifdef HEAVY_H' : - bAdd=False - if bAdd and line[0]!='#': - f.write(line) - if line.strip()=='#else' : - bAdd=True - if line.strip()=='#endif' : - bAdd=True + bAdd=False + if bAdd and line[0]!='#': + f.write(line) + if line.strip()=='#else' : + bAdd=True + if line.strip()=='#endif' : + bAdd=True def assign_mass(r1, r2,ffnonbonded,bCharmm,ff): - #MS open ffnonbonded, remove HEAVY_H, pass it to NBParser - if bCharmm : + #MS open ffnonbonded, remove HEAVY_H, pass it to NBParser + if bCharmm : f=tempfile.NamedTemporaryFile(delete=False) - parse_ffnonbonded_charmm(ffnonbonded,f) - print f.name + parse_ffnonbonded_charmm(ffnonbonded,f) + print(f.name) NBParams = NBParser(f.name,'new',ff) - f.close() - else : + f.close() + else : NBParams = NBParser(ffnonbonded,'new',ff) for atom in r1.atoms+r2.atoms: # print atom.atomtype, atom.name @@ -1240,7 +1240,7 @@ def assign_mass_atp(r1, r2,ffatomtypes): for atom in r1.atoms+r2.atoms: atom.m = mass[atom.atomtype] # print atom.atomtype, atom.name, atom.m - + def rename_to_gmx( r ): for atom in r1.atoms: if atom.name[0].isdigit(): @@ -1258,18 +1258,18 @@ def rename_to_gmx( r ): def rename_to_match_library( m, bCharmm=False ): name_hash = {} for atom in m.atoms: - foo = atom.name + foo = atom.name if atom.name[0].isdigit(): atom.name = atom.name[1:]+atom.name[0] - if bCharmm: - print atom.name - if (atom.resname == 'CYS') and (atom.name == 'HG1'): - atom.name = 'HG' + if bCharmm: + print(atom.name) + if (atom.resname == 'CYS') and (atom.name == 'HG1'): + atom.name = 'HG' if (atom.resname == 'SER') and (atom.name == 'HG1'): atom.name = 'HG' - name_hash[atom.name] = foo + name_hash[atom.name] = foo return name_hash - + def rename_back( m, name_hash ): for atom in m.atoms: atom.name = name_hash[atom.name] @@ -1278,7 +1278,7 @@ def reformat_atom_name( name ): if name[0].isdigit(): name = name[1:]+name[0] return name - + def improps_as_atoms( im, r, use_b = False): im_new = [] for ii in im: @@ -1293,7 +1293,7 @@ def improps_as_atoms( im, r, use_b = False): if atom.nameB == name: a = atom else: - print name + print(name) a = r.fetch( name )[0] new_ii.append( a ) new_ii.extend( ii[4:] ) @@ -1329,13 +1329,13 @@ def write_atp_fnb(fn_atp,fn_nb,r,ff,ffpath): for atom in r.atoms: if atom.atomtype[0:3]=='DUM': - if atom.atomtype not in types: + if atom.atomtype not in types: ofile.write("%-6s %10.6f\n" % (atom.atomtype,atom.m)) - types.append(atom.atomtype) + types.append(atom.atomtype) if atom.atomtypeB[0:3]=='DUM': - if atom.atomtypeB not in types: + if atom.atomtypeB not in types: ofile.write("%-6s %10.6f\n" % (atom.atomtypeB,atom.mB)) - types.append(atom.atomtypeB) + types.append(atom.atomtypeB) ofile.close() types=[] @@ -1351,63 +1351,63 @@ def write_atp_fnb(fn_atp,fn_nb,r,ff,ffpath): ofile=open(fn_nb,'a') else : ofile=open(fn_nb,'w') - print types + print(types) # for opls need to extract the atom name ffnamelower = ff.lower() if( 'opls' in ffnamelower): - dum_real_name = read_nbitp(os.path.join(ffpath,'ffnonbonded.itp')) + dum_real_name = read_nbitp(os.path.join(ffpath,'ffnonbonded.itp')) for atom in r.atoms: if atom.atomtype[0:3]=='DUM': - if atom.atomtype not in types: - if( 'opls' in ffnamelower): - foo = dum_real_name['opls_'+atom.atomtype.split('_')[2]] + if atom.atomtype not in types: + if( 'opls' in ffnamelower): + foo = dum_real_name['opls_'+atom.atomtype.split('_')[2]] ofile.write("%-13s\t\t%3s\t0\t%4.2f\t 0.0000 A 0.00000e+00 0.00000e+00\n" \ - % (atom.atomtype,foo[0],atom.m)) - else: + % (atom.atomtype,foo[0],atom.m)) + else: ofile.write("%-10s\t0\t%4.2f\t 0.0000 A 0.00000e+00 0.00000e+00\n" \ - % (atom.atomtype,atom.m)) - types.append(atom.atomtype) + % (atom.atomtype,atom.m)) + types.append(atom.atomtype) if atom.atomtypeB[0:3]=='DUM': - if atom.atomtypeB not in types: - if( 'opls' in ffnamelower): + if atom.atomtypeB not in types: + if( 'opls' in ffnamelower): foo = dum_real_name['opls_'+atom.atomtypeB.split('_')[2]] ofile.write("%-13s\t\t%3s\t0\t%4.2f\t 0.0000 A 0.00000e+00 0.00000e+00\n" \ % (atom.atomtypeB,foo[0],atom.mB)) - else: + else: ofile.write("%-10s\t0\t%4.2f\t 0.0000 A 0.00000e+00 0.00000e+00\n" \ - % (atom.atomtypeB,atom.mB)) - types.append(atom.atomtypeB) + % (atom.atomtypeB,atom.mB)) + types.append(atom.atomtypeB) ofile.close() - + # lines=fatp.readlines() -# for +# for # types=[] # for line in lines: -# +# # #write output for atomtypes # #write output for ffnonbonded.itp # fnb.write("%-10s\t0\t%4.2f\t 0.0000 A 0.00000e+00 0.00000e+00\n" \ -# % (atom.atomtypeB,atom.mB)) +# % (atom.atomtypeB,atom.mB)) # #MS charmm uses HN instead of H for backbone H on N def rename_atoms_charmm(m): for atom in m.atoms: if atom.name=='H' : - atom.name='HN' + atom.name='HN' if atom.name=='HG' and atom.resname=='CYS' : - atom.name='1HG' + atom.name='1HG' if atom.name=='HG' and atom.resname=='SER' : - atom.name='1HG' + atom.name='1HG' def rename_res_charmm(m): rename={'HIE':'HSE','HID':'HSD','HIP':'HSP','ASH':'ASPP','GLH':'GLUP','LYN':'LSN'} for res in m.residues: - if rename.has_key(res.resname): - res.resname=rename[res.resname] - for atom in res.atoms: - atom.resname=res.resname + if res.resname in rename: + res.resname=rename[res.resname] + for atom in res.atoms: + atom.resname=res.resname def get_ff_path( ff ): ff_path = None @@ -1420,15 +1420,15 @@ def get_ff_path( ff ): elif os.path.isdir(pff): ff_path = pff else: - print >>sys.stderr,' Error: forcefield path "%s" not found' % ff + print(' Error: forcefield path "%s" not found' % ff, file=sys.stderr) sys.exit(0) else: ff_path = ff - print 'Opening forcefield: %s' % ff_path + print('Opening forcefield: %s' % ff_path) return ff_path - + files= [ FileOption("-pdb1", "r",["pdb"],"a1.pdb",""), FileOption("-pdb2", "r",["pdb"],"a2.pdb",""), @@ -1449,7 +1449,7 @@ def get_ff_path( ff ): Option( "-H2heavy", "bool", True, "allow morphing between hydrogens and heavy atoms"), Option( "-dna", "bool", False, "generate hybrid residue for the DNA nucleotides"), Option( "-rna", "bool", False, "generate hybrid residue for the RNA nucleotides"), - ] + ] help_text = ('The script creates hybrid structure (.pdb) and topology database entries (.rtp, .mtp).', 'Input: two pdb files aligned on the backbone and path to the force field files.', @@ -1460,7 +1460,7 @@ def get_ff_path( ff ): 'Please cite:', 'Vytautas Gapsys, Servaas Michielssens, Daniel Seeliger and Bert L. de Groot.', 'Automated Protein Structure and Topology Generation for Alchemical Perturbations.', - 'J. Comput. Chem. 2015, 36, 348-354. DOI: 10.1002/jcc.23804', + 'J. Comput. Chem. 2015, 36, 348-354. DOI: 10.1002/jcc.23804', '', 'Old pmx (pymacs) version:', 'Daniel Seeliger and Bert L. de Groot. Protein Thermostability Calculations Using', @@ -1471,8 +1471,8 @@ def get_ff_path( ff ): ) #options=[Option("-ff", "string", False ,"aminoacids.rtp")] -cmdl = Commandline( sys.argv, options = options, - fileoptions = files, +cmdl = Commandline( sys.argv, options = options, + fileoptions = files, program_desc = help_text, check_for_existing_files = False ) if "charmm" in cmdl['-ft'].lower(): @@ -1506,7 +1506,7 @@ def get_ff_path( ff ): rr_name = dna_mutation_naming(aa1,aa2) elif bRNA: rr_name = rna_mutation_naming(aa1,aa2) -elif rr_name in noncanonical_aa.keys(): +elif rr_name in list(noncanonical_aa.keys()): rr_name = noncanonical_aa[rr_name] m1.get_symbol() @@ -1619,85 +1619,85 @@ def get_ff_path( ff ): ######## nucleic acids ######## if bDNA: if (('5' in r1.resname) and ('5' not in r2.resname)) or \ - (('3' in r1.resname) and ('3' not in r2.resname)) or \ - (('5' in r2.resname) and ('5' not in r1.resname)) or \ - (('3' in r2.resname) and ('3' not in r1.resname)): - print "Cannot mutate terminal nucleic acid to non-terminal or a terminal of the other end (e.g. 5' to 3')" - sys.exit(0) - if use_standard_dna_pair_list.has_key( r1.resname ) and \ - r2.resname in use_standard_dna_pair_list[r1.resname]: - print "PURINE <-> PYRIMIDINE" + (('3' in r1.resname) and ('3' not in r2.resname)) or \ + (('5' in r2.resname) and ('5' not in r1.resname)) or \ + (('3' in r2.resname) and ('3' not in r1.resname)): + print("Cannot mutate terminal nucleic acid to non-terminal or a terminal of the other end (e.g. 5' to 3')") + sys.exit(0) + if r1.resname in use_standard_dna_pair_list and \ + r2.resname in use_standard_dna_pair_list[r1.resname]: + print("PURINE <-> PYRIMIDINE") if bCharmm : atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_dna_pair_list_charmm) else : atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_dna_pair_list) - elif use_standard_dna_5term_pair_list.has_key( r1.resname ) and \ - r2.resname in use_standard_dna_5term_pair_list[r1.resname]: - print "PURINE <-> PYRIMIDINE: 5term" + elif r1.resname in use_standard_dna_5term_pair_list and \ + r2.resname in use_standard_dna_5term_pair_list[r1.resname]: + print("PURINE <-> PYRIMIDINE: 5term") if bCharmm : atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_dna_5term_pair_list_charmm) - else: + else: atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_dna_5term_pair_list) - elif use_standard_dna_3term_pair_list.has_key( r1.resname ) and \ - r2.resname in use_standard_dna_3term_pair_list[r1.resname]: - print "PURINE <-> PYRIMIDINE: 3term" + elif r1.resname in use_standard_dna_3term_pair_list and \ + r2.resname in use_standard_dna_3term_pair_list[r1.resname]: + print("PURINE <-> PYRIMIDINE: 3term") if bCharmm : atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_dna_3term_pair_list_charmm) - else: + else: atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_dna_3term_pair_list) else: - print "PURINE <-> PURINE PYRIMIDINE <-> PYRIMIDINE" + print("PURINE <-> PURINE PYRIMIDINE <-> PYRIMIDINE") atom_pairs, dummies = make_pairs( r1, r2,bCharmm, bH2heavy, bDNA=True ) elif bRNA: if (('5' in r1.resname) and ('5' not in r2.resname)) or \ - (('3' in r1.resname) and ('3' not in r2.resname)) or \ - (('5' in r2.resname) and ('5' not in r1.resname)) or \ - (('3' in r2.resname) and ('3' not in r1.resname)): - print "Cannot mutate terminal nucleic acid to non-terminal or a terminal of the other end (e.g. 5' to 3')" - sys.exit(0) - if use_standard_rna_pair_list.has_key( r1.resname ) and \ - r2.resname in use_standard_rna_pair_list[r1.resname]: - print "PURINE <-> PYRIMIDINE" + (('3' in r1.resname) and ('3' not in r2.resname)) or \ + (('5' in r2.resname) and ('5' not in r1.resname)) or \ + (('3' in r2.resname) and ('3' not in r1.resname)): + print("Cannot mutate terminal nucleic acid to non-terminal or a terminal of the other end (e.g. 5' to 3')") + sys.exit(0) + if r1.resname in use_standard_rna_pair_list and \ + r2.resname in use_standard_rna_pair_list[r1.resname]: + print("PURINE <-> PYRIMIDINE") # if bCharmm : # atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_rna_pair_list_charmm) # else : atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_rna_pair_list) - elif use_standard_rna_5term_pair_list.has_key( r1.resname ) and \ - r2.resname in use_standard_rna_5term_pair_list[r1.resname]: - print "PURINE <-> PYRIMIDINE: 5term" + elif r1.resname in use_standard_rna_5term_pair_list and \ + r2.resname in use_standard_rna_5term_pair_list[r1.resname]: + print("PURINE <-> PYRIMIDINE: 5term") # if bCharmm : # atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_rna_5term_pair_list_charmm) -# else: +# else: atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_rna_5term_pair_list) - elif use_standard_rna_3term_pair_list.has_key( r1.resname ) and \ - r2.resname in use_standard_rna_3term_pair_list[r1.resname]: - print "PURINE <-> PYRIMIDINE: 3term" + elif r1.resname in use_standard_rna_3term_pair_list and \ + r2.resname in use_standard_rna_3term_pair_list[r1.resname]: + print("PURINE <-> PYRIMIDINE: 3term") # if bCharmm : # atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_rna_3term_pair_list_charmm) -# else: +# else: atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_rna_3term_pair_list) else: - print "PURINE <-> PURINE PYRIMIDINE <-> PYRIMIDINE" + print("PURINE <-> PURINE PYRIMIDINE <-> PYRIMIDINE") atom_pairs, dummies = make_pairs( r1, r2,bCharmm, bH2heavy, bDNA=False, bRNA=True ) ####### amino acids ######### #ring-res 2 ring-res -elif use_standard_pair_list.has_key( r1.resname ) and \ +elif r1.resname in use_standard_pair_list and \ r2.resname in use_standard_pair_list[r1.resname]: - print "ENTERED STANDARD" + print("ENTERED STANDARD") if bCharmm : - if cbeta: - atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_list_charmmC) - else: + if cbeta: + atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_list_charmmC) + else: atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_list_charmm) else : - if cbeta: - atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_listC) - else: + if cbeta: + atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_listC) + else: atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_list) #ring-res 2 non-ring-res: T,A,V,I elif (r1.resname in res_with_rings and r2.resname in res_diff_Cb ) or \ (r2.resname in res_with_rings and r1.resname in res_diff_Cb ): - print "ENTERED T,A,V,I" + print("ENTERED T,A,V,I") if bCharmm : atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_list_charmmC) else : @@ -1705,44 +1705,44 @@ def get_ff_path( ff ): #ring-res 2 non-ring-res: G,P elif (r1.resname in res_with_rings and r2.resname in res_gly_pro ) or \ (r2.resname in res_with_rings and r1.resname in res_gly_pro ): - print "ENTERED G,P" + print("ENTERED G,P") if bCharmm : atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_list_charmmD) else : atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_listD) -#ringed residues by atom names -elif merge_by_name_list.has_key( r1.resname ) and r2.resname in merge_by_name_list[r1.resname]: +#ringed residues by atom names +elif r1.resname in merge_by_name_list and r2.resname in merge_by_name_list[r1.resname]: if cbeta: if bCharmm : atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_list_charmmC) else : atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_listC) else: - print "ENTERED MERGE BY NAMES" - atom_pairs, dummies = merge_by_names( r1, r2 ) #make_predefined_pairs( r1, r2, standard_pair_list) + print("ENTERED MERGE BY NAMES") + atom_pairs, dummies = merge_by_names( r1, r2 ) #make_predefined_pairs( r1, r2, standard_pair_list) #ring-res 2 non-ring-res elif r1.resname in res_with_rings or \ r2.resname in res_with_rings: - print "ENTERED RINGS" + print("ENTERED RINGS") if bCharmm : - if cbeta: - atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_list_charmmC) - else: + if cbeta: + atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_list_charmmC) + else: atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_list_charmmB) else : - if cbeta: - atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_listC) - else: + if cbeta: + atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_listC) + else: atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_listB) -else: - print "ENTERED SIMPLE" +else: + print("ENTERED SIMPLE") if cbeta: - if (r1.resname=='GLY') or (r2.resname=='GLY'): + if (r1.resname=='GLY') or (r2.resname=='GLY'): if bCharmm : atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_list_charmmD) else : atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_listD) - else: + else: if bCharmm : atom_pairs, dummies = make_predefined_pairs( r1, r2, standard_pair_list_charmmC) else : @@ -1811,7 +1811,6 @@ def get_ff_path( ff ): mtp_out = open(rr_name+'.mtp','w') if bDNA or bRNA: - write_mtp(mtp_out, r1, ii_list, False, dihi_list) + write_mtp(mtp_out, r1, ii_list, False, dihi_list) else: - write_mtp(mtp_out, r1, ii_list, rot, dihi_list) - + write_mtp(mtp_out, r1, ii_list, rot, dihi_list) diff --git a/pmx/scripts/generate_hybrid_topology.py b/pmx/scripts/generate_hybrid_topology.py index 08c9b275..89b609c1 100755 --- a/pmx/scripts/generate_hybrid_topology.py +++ b/pmx/scripts/generate_hybrid_topology.py @@ -39,10 +39,10 @@ 'DTA','DTG','DTC','DGA','DGC','DGT', 'RAU','RAC','RAG','RCU','RCG','RCA', 'RUA','RUG','RUC','RGA','RGC','RGU', - 'D5K','D5L','D5M','D5N','D5O','D5P','D5R','D5S','D5T','D5X','D5Y','D5Z', - 'D3K','D3L','D3M','D3N','D3O','D3P','D3R','D3S','D3T','D3X','D3Y','D3Z', - 'R5K','R5L','R5M','R5N','R5O','R5P','R5R','R5S','R5T','R5X','R5Y','R5Z', - 'R3K','R3L','R3M','R3N','R3O','R3P','R3R','R3S','R3T','R3X','R3Y','R3Z', + 'D5K','D5L','D5M','D5N','D5O','D5P','D5R','D5S','D5T','D5X','D5Y','D5Z', + 'D3K','D3L','D3M','D3N','D3O','D3P','D3R','D3S','D3T','D3X','D3Y','D3Z', + 'R5K','R5L','R5M','R5N','R5O','R5P','R5R','R5S','R5T','R5X','R5Y','R5Z', + 'R3K','R3L','R3M','R3N','R3O','R3P','R3R','R3S','R3T','R3X','R3Y','R3Z', ] @@ -59,11 +59,11 @@ def check_case(atoms): return A, B def dump_atoms_and_exit( msg, atoms ): - print >>sys.stderr, 'err_> ', msg - print >>sys.stderr, 'err_> name resname atomtype atomtypeB bondtype bondtypeB' + print('err_> ', msg, file=sys.stderr) + print('err_> name resname atomtype atomtypeB bondtype bondtypeB', file=sys.stderr) for atom in atoms: - print >>sys.stderr, atom.name, atom.resname, atom.atomtype, atom.atomtypeB, atom.type, atom.typeB - print >>sys.stderr, 'err_> Exiting' + print(atom.name, atom.resname, atom.atomtype, atom.atomtypeB, atom.type, atom.typeB, file=sys.stderr) + print('err_> Exiting', file=sys.stderr) sys.exit(1) def atoms_morphe(atoms): @@ -101,19 +101,19 @@ def find_bonded_entries( topol ): b.extend([astate,bstate]) # catch errors elif 'D' in B and 'D' in A: - print 'Error: fake bond %s-%s (%s-%s -> %s-%s)' % (a1.name,a2.name,a1.atomtype,a2.atomtype, a1.atomtypeB,a2.atomtypeB) + print('Error: fake bond %s-%s (%s-%s -> %s-%s)' % (a1.name,a2.name,a1.atomtype,a2.atomtype, a1.atomtypeB,a2.atomtypeB)) sys.exit(1) if astate == None: - print 'Error A: No bond entry found for astate %s-%s (%s-%s -> %s-%s)' % (a1.name,a2.name,a1.atomtype,a2.atomtype, a1.type,a2.type) - print 'Resi = %s' % a1.resname + print('Error A: No bond entry found for astate %s-%s (%s-%s -> %s-%s)' % (a1.name,a2.name,a1.atomtype,a2.atomtype, a1.type,a2.type)) + print('Resi = %s' % a1.resname) error_occured = True if bstate == None: - print 'Error B: No bond entry found for bstate %s-%s (%s-%s -> %s-%s)' % (a1.name,a2.name,a1.atomtypeB,a2.atomtypeB, a1.typeB,a2.typeB) + print('Error B: No bond entry found for bstate %s-%s (%s-%s -> %s-%s)' % (a1.name,a2.name,a1.atomtypeB,a2.atomtypeB, a1.typeB,a2.typeB)) error_occured = True if error_occured: sys.exit(1) - print 'log_> Making bonds for state B -> %d bonds with perturbed atoms' % count + print('log_> Making bonds for state B -> %d bonds with perturbed atoms' % count) def find_angle_entries(topol): count = 0 @@ -127,10 +127,10 @@ def find_angle_entries(topol): A, B = check_case([a1,a2,a3]) count+=1 if 'D' in A and 'D' in B: # fake angle - if func==5 : + if func==5 : astate = [1,0,0,0,0] bstate = [1,0,0,0,0] - else : + else : astate = [1,0,0] bstate = [1,0,0] a.extend([astate,bstate]) @@ -149,7 +149,7 @@ def find_angle_entries(topol): astate = topol.BondedParams.get_angle_param(a1.type,a2.type,a3.type) bstate = topol.BondedParams.get_angle_param(a1.typeB,a2.typeB,a3.typeB) a.extend([astate, bstate]) -# print '%s %s %s' % (a1.name, a2.name, a3.name) +# print '%s %s %s' % (a1.name, a2.name, a3.name) else: astate = topol.BondedParams.get_angle_param(a1.type,a2.type,a3.type) bstate = astate @@ -159,18 +159,18 @@ def find_angle_entries(topol): if bstate is None: dump_atoms_and_exit( "No angle entry (state B)", [a1,a2,a3] ) - print 'log_> Making angles for state B -> %d angles with perturbed atoms' % count + print('log_> Making angles for state B -> %d angles with perturbed atoms' % count) def check_dih_ILDN_OPLS( topol, rlist, rdic, a1, a2, a3, a4 ): counter = 0 for r in rlist: - if( r.id == a2.resnr ): - idx = r.id - 1 + if( r.id == a2.resnr ): + idx = r.id - 1 dih = rdic[r.resname][3] for d in dih: - if( counter == 1): - break + if( counter == 1): + break al = [] for name in d[:4]: atom = r.fetch(name)[0] @@ -197,12 +197,12 @@ def check_dih_ILDN_OPLS( topol, rlist, rdic, a1, a2, a3, a4 ): # print 'torsion_undef %s %s' % (d[4],d[5]) counter = 3 break - ##### checks for ILDN ##### - if( (d[4].startswith('torsion')) and (d[5].startswith('torsion')) ): -# print 'torsion %s %s' % (d[4],d[5]) - counter = 42 - break - elif( (d[4].startswith('torsion')) and ('un' in d[5]) ): + ##### checks for ILDN ##### + if( (d[4].startswith('torsion')) and (d[5].startswith('torsion')) ): +# print 'torsion %s %s' % (d[4],d[5]) + counter = 42 + break + elif( (d[4].startswith('torsion')) and ('un' in d[5]) ): # print 'torsion_undef %s %s' % (d[4],d[5]) counter = 2 break @@ -210,10 +210,10 @@ def check_dih_ILDN_OPLS( topol, rlist, rdic, a1, a2, a3, a4 ): # print 'torsion_undef %s %s' % (d[4],d[5]) counter = 3 break - elif( 'un' in d[4] ): -# print 'undef %s' %d[4] - counter = 1 - break + elif( 'un' in d[4] ): +# print 'undef %s' %d[4] + counter = 1 + break return counter @@ -221,29 +221,29 @@ def is_dih_undef(visited_dih, d ): encountered = 0 undef = 0 for dih in visited_dih: - if( dih[0].id==d[0].id and dih[1].id==d[1].id and dih[2].id==d[2].id and dih[3].id==d[3].id ): - if (dih[-1] == 'undefA'): - undef = 1 - break + if( dih[0].id==d[0].id and dih[1].id==d[1].id and dih[2].id==d[2].id and dih[3].id==d[3].id ): + if (dih[-1] == 'undefA'): + undef = 1 + break elif (dih[-1] == 'undefB'): undef = 2 - break + break elif (dih[-1] == 'undefA_ildn'): undef = 3 - break + break elif (dih[-1] == 'undefB_ildn'): undef = 4 - break - else: - encountered = 1 - break + break + else: + encountered = 1 + break return (undef,encountered) def is_dih_encountered_strict(visited_dih, d, encountered): for dih in visited_dih: if( dih[0].id==d[0].id and dih[1].id==d[1].id and dih[2].id==d[2].id and dih[3].id==d[3].id ): encountered = 1 - break + break return encountered @@ -256,27 +256,27 @@ def find_dihedral_entries( topol, rlist, rdic, dih_predef_default, ): for d in topol.dihedrals: if len(d) >= 6: - # only consider the dihedral, if it has not been encountered so far - undef = 0 - encountered = 0 - - (undef,encountered) = is_dih_undef(dih_predef_default, d) - encountered = is_dih_encountered_strict(visited_dih, d, encountered) - if(encountered == 1): - continue - - visited_dih.append(d) - - if(undef==3 or undef==4): - a1 = d[0] - a2 = d[1] - a3 = d[2] - a4 = d[3] - val = '' - func = 9 + # only consider the dihedral, if it has not been encountered so far + undef = 0 + encountered = 0 + + (undef,encountered) = is_dih_undef(dih_predef_default, d) + encountered = is_dih_encountered_strict(visited_dih, d, encountered) + if(encountered == 1): + continue + + visited_dih.append(d) + + if(undef==3 or undef==4): + a1 = d[0] + a2 = d[1] + a3 = d[2] + a4 = d[3] + val = '' + func = 9 elif(len(d) == 6): a1,a2,a3,a4, func, val = d - else: + else: a1,a2,a3,a4, func, val, rest = d backup_d = d[:6] @@ -290,14 +290,14 @@ def find_dihedral_entries( topol, rlist, rdic, dih_predef_default, ): d.append('NULL') else: count +=1 - astate = [] - bstate = [] + astate = [] + bstate = [] if A == 'AAAA' and B!='AAAA': foo = topol.BondedParams.get_dihedral_param(a1.type,a2.type,a3.type,a4.type, func) - #need to check if the dihedral has torsion pre-defined - counter = check_dih_ILDN_OPLS(topol,rlist,rdic, a1, a2, a3, a4) - if( counter == 42 ): - continue + #need to check if the dihedral has torsion pre-defined + counter = check_dih_ILDN_OPLS(topol,rlist,rdic, a1, a2, a3, a4) + if( counter == 42 ): + continue for ast in foo: if( counter == 0 ): @@ -332,67 +332,67 @@ def find_dihedral_entries( topol, rlist, rdic, dih_predef_default, ): elif A=='AAAA' and B=='AAAA': - ### VG ### - # disappear/appear dihedrals, do not morphe # + ### VG ### + # disappear/appear dihedrals, do not morphe # if val=='': - if(undef != 4): + if(undef != 4): astate = topol.BondedParams.get_dihedral_param(a1.type,a2.type,a3.type,a4.type, func) else: - if(undef != 4): + if(undef != 4): astate = topol.BondedParams.get_dihedral_param(a1.type,a2.type,a3.type,a4.type, func) # if types_morphe([a1,a2,a3,a4]): - if (undef != 3): - bstate = topol.BondedParams.get_dihedral_param(a1.typeB,a2.typeB,a3.typeB,a4.typeB, func) + if (undef != 3): + bstate = topol.BondedParams.get_dihedral_param(a1.typeB,a2.typeB,a3.typeB,a4.typeB, func) # else: -# if (undef != 3): +# if (undef != 3): # bstate = astate[:] - if(undef==1 and astate == [] ): - continue - elif(undef==1 and (astate[0][0]==4 or astate[0][0]==2)): - continue - elif(undef==2 and bstate == []): - continue - elif(undef==2 and (bstate[0][0]==4 or bstate[0][0]==2) ): - continue + if(undef==1 and astate == [] ): + continue + elif(undef==1 and (astate[0][0]==4 or astate[0][0]==2)): + continue + elif(undef==2 and bstate == []): + continue + elif(undef==2 and (bstate[0][0]==4 or bstate[0][0]==2) ): + continue #need to check if the dihedral has torsion pre-defined counter = check_dih_ILDN_OPLS(topol,rlist,rdic, a1, a2, a3, a4) - if( counter == 42): #torsion for both states defined, change nothing - continue + if( counter == 42): #torsion for both states defined, change nothing + continue - # A state disappears (when going to B) + # A state disappears (when going to B) for ast in astate: - if(counter == 0): - d[5] = ast + if(counter == 0): + d[5] = ast if(ast[0] == 3): bst = [ast[0], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] elif(ast[0] == 2): bst = [ast[0], ast[1], 0.0] else: - bst = [ ast[0], ast[1], 0.0, ast[-1] ] - if( len(d)==6 ): - d.append(bst) - else: - d[6] = bst - counter = 1 -# print '%s' %d - elif( (counter==1) or (counter==3) ): - alus = backup_d[:] - alus[5] = ast + bst = [ ast[0], ast[1], 0.0, ast[-1] ] + if( len(d)==6 ): + d.append(bst) + else: + d[6] = bst + counter = 1 +# print '%s' %d + elif( (counter==1) or (counter==3) ): + alus = backup_d[:] + alus[5] = ast if(ast[0] == 3): bst = [ast[0], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] elif(ast[0] == 2): bst = [ast[0], ast[1], 0.0] else: bst = [ ast[0], ast[1], 0.0, ast[-1] ] - alus.append(bst) - dih9.append(alus) + alus.append(bst) + dih9.append(alus) - # B state disappears (when going to A) - # all must go to the new (appendable) dihedrals + # B state disappears (when going to A) + # all must go to the new (appendable) dihedrals for bst in bstate: if(counter == 0): if(bst[0] == 3): @@ -401,7 +401,7 @@ def find_dihedral_entries( topol, rlist, rdic, dih_predef_default, ): ast = [bst[0], bst[1], 0.0] else: ast = [ bst[0], bst[1], 0.0, bst[-1] ] - d[5] = ast + d[5] = ast if( len(d)==6 ): d.append(bst) else: @@ -421,38 +421,38 @@ def find_dihedral_entries( topol, rlist, rdic, dih_predef_default, ): dih9.append(alus) - if astate == None : - print 'Error: No dihedral angle found (state A: predefined state B) for:' - print a1.resname, a2.resname, a3.resname, a4.resname - print a1.name, a2.name, a3.name, a4.name, func - print a1.atomtype, a2.atomtype, a3.atomtype, a4.atomtype - print a1.type, a2.type, a3.type, a4.type - print a1.atomtypeB, a2.atomtypeB, a3.atomtypeB, a4.atomtypeB - print a1.typeB, a2.typeB, a3.typeB, a4.typeB - print astate - print d + if astate == None : + print('Error: No dihedral angle found (state A: predefined state B) for:') + print(a1.resname, a2.resname, a3.resname, a4.resname) + print(a1.name, a2.name, a3.name, a4.name, func) + print(a1.atomtype, a2.atomtype, a3.atomtype, a4.atomtype) + print(a1.type, a2.type, a3.type, a4.type) + print(a1.atomtypeB, a2.atomtypeB, a3.atomtypeB, a4.atomtypeB) + print(a1.typeB, a2.typeB, a3.typeB, a4.typeB) + print(astate) + print(d) sys.exit(1) if bstate == None : - print 'Error: No dihedral angle found (state B: predefined state A) for:' - print a1.resname, a2.resname, a3.resname, a4.resname - print a1.name, a2.name, a3.name, a4.name, func - print a1.atomtype, a2.atomtype, a3.atomtype, a4.atomtype - print a1.type, a2.type, a3.type, a4.type - print a1.atomtypeB, a2.atomtypeB, a3.atomtypeB, a4.atomtypeB - print a1.typeB, a2.typeB, a3.typeB, a4.typeB - print d + print('Error: No dihedral angle found (state B: predefined state A) for:') + print(a1.resname, a2.resname, a3.resname, a4.resname) + print(a1.name, a2.name, a3.name, a4.name, func) + print(a1.atomtype, a2.atomtype, a3.atomtype, a4.atomtype) + print(a1.type, a2.type, a3.type, a4.type) + print(a1.atomtypeB, a2.atomtypeB, a3.atomtypeB, a4.atomtypeB) + print(a1.typeB, a2.typeB, a3.typeB, a4.typeB) + print(d) sys.exit(1) - ### VG ### - ### the previous two if sentences will kill the execution if anything goes wrong ### - ### therefore, I am not afraid to do d.append() already in the previous steps ### - ### VG ### + ### VG ### + ### the previous two if sentences will kill the execution if anything goes wrong ### + ### therefore, I am not afraid to do d.append() already in the previous steps ### + ### VG ### topol.dihedrals.extend(dih9) - print 'log_> Making dihedrals for state B -> %d dihedrals with perturbed atoms' % count - print 'log_> Removed %d fake dihedrals' % nfake + print('log_> Making dihedrals for state B -> %d dihedrals with perturbed atoms' % count) + print('log_> Removed %d fake dihedrals' % nfake) def get_torsion_multiplicity( name ): @@ -469,13 +469,13 @@ def explicit_defined_dihedrals(filename,ff): if line.startswith('#define'): entr = line.split() name = entr[1] - if( ffnamelower.startswith('amber') ): - params = [9,float(entr[2]),float(entr[3]),int(entr[4])] - elif( ffnamelower.startswith('opls') ): - if( len(entr) == 8): #dihedral - params = [3,float(entr[2]),float(entr[3]),float(entr[4]),float(entr[5]),float(entr[6]),float(entr[7])] - elif( len(entr) == 5): - params = [1,float(entr[2]),float(entr[3]),float(entr[4])] + if( ffnamelower.startswith('amber') ): + params = [9,float(entr[2]),float(entr[3]),int(entr[4])] + elif( ffnamelower.startswith('opls') ): + if( len(entr) == 8): #dihedral + params = [3,float(entr[2]),float(entr[3]),float(entr[4]),float(entr[5]),float(entr[6]),float(entr[7])] + elif( len(entr) == 5): + params = [1,float(entr[2]),float(entr[3]),float(entr[4])] output[name] = params return output @@ -484,7 +484,7 @@ def explicit_defined_dihedrals(filename,ff): def is_ildn_dih_encountered(ildn_used, d, encountered): for dih in ildn_used: if( dih[0]==d[0] and dih[1]==d[1] and dih[2]==d[2] and dih[3]==d[3] and dih[4]==d[4]): - encountered = 1 + encountered = 1 return encountered @@ -500,7 +500,7 @@ def find_predefined_dihedrals(topol, rlist, rdic, ffbonded, dih_predef_default, dih = rdic[r.resname][3] imp = rdic[r.resname][2] for d in imp+dih: -# print 'BBBBBBBBBB %s %s %s' %(d[:4],d[4],d[5]) +# print 'BBBBBBBBBB %s %s %s' %(d[:4],d[4],d[5]) al = [] for name in d[:4]: if name.startswith('+'): @@ -529,21 +529,21 @@ def find_predefined_dihedrals(topol, rlist, rdic, ffbonded, dih_predef_default, #the following checks are needed for amber99sb*-ildn #do not overwrite proper (type9) with improper (type4) if('default-star' in d[4] and dx[4]==9): - print '%s' %d[4] + print('%s' %d[4]) continue #is the dihedral already found for ILDN - encountered = 0 - foobar = [ dx[0].id, dx[1].id, dx[2].id, dx[3].id, d[4] ] - encountered = is_ildn_dih_encountered(ildn_used,foobar,encountered) - foobar = [ dx[0].id, dx[1].id, dx[2].id, dx[3].id, d[5] ] - encountered = is_ildn_dih_encountered(ildn_used,foobar,encountered) - if( encountered==1 ): - continue - if ( 'tors' in d[4] ):#'torsion' in dx[5] ): - if ( ('tors' not in dx[5]) ): - continue - - #check for opls + encountered = 0 + foobar = [ dx[0].id, dx[1].id, dx[2].id, dx[3].id, d[4] ] + encountered = is_ildn_dih_encountered(ildn_used,foobar,encountered) + foobar = [ dx[0].id, dx[1].id, dx[2].id, dx[3].id, d[5] ] + encountered = is_ildn_dih_encountered(ildn_used,foobar,encountered) + if( encountered==1 ): + continue + if ( 'tors' in d[4] ):#'torsion' in dx[5] ): + if ( ('tors' not in dx[5]) ): + continue + + #check for opls encountered = 0 foobar = [ dx[0].id, dx[1].id, dx[2].id, dx[3].id, d[4] ] encountered = is_ildn_dih_encountered(opls_used,foobar,encountered) @@ -553,23 +553,23 @@ def find_predefined_dihedrals(topol, rlist, rdic, ffbonded, dih_predef_default, continue if ( 'dih_' in d[4] ):#'dih_' in dx[5] ): if ( ('dih_' not in dx[5]) ): - continue + continue A,B = check_case(al[:4]) paramA = topol.BondedParams.get_dihedral_param(al[0].type,al[1].type,al[2].type,al[3].type, func) paramB = topol.BondedParams.get_dihedral_param(al[0].typeB,al[1].typeB,al[2].typeB,al[3].typeB, func) - astate = [] - bstate = [] - backup_dx = dx[:] - backup_dx2 = dx[:] + astate = [] + bstate = [] + backup_dx = dx[:] + backup_dx2 = dx[:] - multA = 0 - multB = 0 + multA = 0 + multB = 0 if d[4] == 'default-A': #amber99sb - if 'un' in d[5]: - backup_dx2.append('undefB') - dih_predef_default.append(backup_dx2) + if 'un' in d[5]: + backup_dx2.append('undefB') + dih_predef_default.append(backup_dx2) astate = paramA elif d[4] == 'default-B': #amber99sb if 'un' in d[5]: @@ -577,26 +577,26 @@ def find_predefined_dihedrals(topol, rlist, rdic, ffbonded, dih_predef_default, dih_predef_default.append(backup_dx2) astate = paramB elif d[4] == 'default-star': #amber99sb* - foo = [4, 105.4, 0.75, 1] - astate.append(foo) - elif d[4].startswith('torsion_'): #amber99sb-ildn + foo = [4, 105.4, 0.75, 1] + astate.append(foo) + elif d[4].startswith('torsion_'): #amber99sb-ildn if 'un' in d[5]: backup_dx2.append('undefB_ildn') dih_predef_default.append(backup_dx2) - foo = explicit_def[d[4]] - astate.append(foo) - foobar = [ dx[0].id, dx[1].id, dx[2].id, dx[3].id, d[4] ] - ildn_used.append(foobar) - func = 9 - elif d[4].startswith('dih_'): #opls proper + foo = explicit_def[d[4]] + astate.append(foo) + foobar = [ dx[0].id, dx[1].id, dx[2].id, dx[3].id, d[4] ] + ildn_used.append(foobar) + func = 9 + elif d[4].startswith('dih_'): #opls proper if 'un' in d[5]: backup_dx2.append('undefB') - dih_predef_default.append(backup_dx2) - foo = explicit_def[d[4]] - astate.append(foo) - foobar = [ dx[0].id, dx[1].id, dx[2].id, dx[3].id, d[4] ] - opls_used.append(foobar) - func = 3 + dih_predef_default.append(backup_dx2) + foo = explicit_def[d[4]] + astate.append(foo) + foobar = [ dx[0].id, dx[1].id, dx[2].id, dx[3].id, d[4] ] + opls_used.append(foobar) + func = 3 elif d[4].startswith('improper_'): #opls improper if 'un' in d[5]: backup_dx2.append('undefB') @@ -607,12 +607,12 @@ def find_predefined_dihedrals(topol, rlist, rdic, ffbonded, dih_predef_default, opls_used.append(foobar) func = 1 elif 'un' in d[4]: #amber99sb-ildn and opls and others - if d[5].startswith('torsion_'): + if d[5].startswith('torsion_'): backup_dx2.append('undefA_ildn') - else: - backup_dx2.append('undefA') + else: + backup_dx2.append('undefA') dih_predef_default.append(backup_dx2) -# print "A undef %s" %d[4] +# print "A undef %s" %d[4] astate = '' else: astate = d[4] @@ -623,14 +623,14 @@ def find_predefined_dihedrals(topol, rlist, rdic, ffbonded, dih_predef_default, bstate = paramB elif d[5] == 'default-star': #amber99sb* foo = [4, 105.4, 0.75, 1] - bstate.append(foo) + bstate.append(foo) elif d[5].startswith('torsion_'): #amber99sb-ildn foo = explicit_def[d[5]] -# print "B %s %s" %(d[5],foo) - bstate.append(foo) - foobar = [ dx[0].id, dx[1].id, dx[2].id, dx[3].id, d[5] ] - ildn_used.append(foobar) - func = 9 +# print "B %s %s" %(d[5],foo) + bstate.append(foo) + foobar = [ dx[0].id, dx[1].id, dx[2].id, dx[3].id, d[5] ] + ildn_used.append(foobar) + func = 9 elif d[5].startswith('dih_'): #opls proper foo = explicit_def[d[5]] bstate.append(foo) @@ -649,40 +649,40 @@ def find_predefined_dihedrals(topol, rlist, rdic, ffbonded, dih_predef_default, bstate = d[5] - ### VG ### - # this should work for ILDN # - #MS: only for type 9? - #VG: for all types + ### VG ### + # this should work for ILDN # + #MS: only for type 9? + #VG: for all types - # A state + # A state counter = 0 -# if not bCharmm : +# if not bCharmm : for foo in astate: - if( counter == 0 ): - dx[4] = func - dx[5] = foo - if(func == 3): + if( counter == 0 ): + dx[4] = func + dx[5] = foo + if(func == 3): bar = [foo[0], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] - elif(func == 2): + elif(func == 2): bar = [foo[0], foo[1],0.0] - else: + else: bar = [foo[0], foo[1],0.0, foo[-1] ] dx.append(bar) - else: - alus = backup_dx[:] - alus[5] = foo + else: + alus = backup_dx[:] + alus[5] = foo if(func == 3): bar = [foo[0], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] - elif(func == 2): + elif(func == 2): bar = [foo[0], foo[1],0.0] else: bar = [foo[0], foo[1],0.0, foo[-1] ] - alus.append(bar) - dih9.append(alus) -# print "new %s %s %s %s %s %s" %(dx[0].id,dx[1].id,dx[2].id,dx[3].id,d[4],dx) + alus.append(bar) + dih9.append(alus) +# print "new %s %s %s %s %s %s" %(dx[0].id,dx[1].id,dx[2].id,dx[3].id,d[4],dx) counter = 1 - # B state + # B state for foo in bstate: if( counter == 0 ): dx[4] = func @@ -692,11 +692,11 @@ def find_predefined_dihedrals(topol, rlist, rdic, ffbonded, dih_predef_default, bar = [foo[0], foo[1],0.0] else: bar = [foo[0], foo[1],0.0, foo[-1] ] - dx[5] = bar + dx[5] = bar dx.append(foo) else: alus = backup_dx[:] -# print "impr %s %s %s %s %s %s" %(dx[0].id,dx[1].id,dx[2].id,dx[3].id,d[4],bstate) +# print "impr %s %s %s %s %s %s" %(dx[0].id,dx[1].id,dx[2].id,dx[3].id,d[4],bstate) if(func == 3): bar = [foo[0], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] elif(func == 2): @@ -708,7 +708,7 @@ def find_predefined_dihedrals(topol, rlist, rdic, ffbonded, dih_predef_default, dih9.append(alus) counter = 1 -# print "testing %s %s %s %s %s %s" %(bstate, dx,dx[0].id,dx[1].id,dx[2].id,dx[3].id) +# print "testing %s %s %s %s %s %s" %(bstate, dx,dx[0].id,dx[1].id,dx[2].id,dx[3].id) topol.dihedrals.extend(dih9) @@ -720,7 +720,7 @@ def __str__(self): return repr(self.s) def get_hybrid_residue(residue_name, mtp_file = 'ffamber99sb.mtp', version = 'old'): - print 'log_> Scanning database for %s ' % residue_name + print('log_> Scanning database for %s ' % residue_name) resi, bonds, imps, diheds, rotdic = read_mtp_entry(residue_name, filename = mtp_file, version = version) if len(resi.atoms) == 0: raise mtpError("Hybrid residue %s not found in %s" % (residue_name, mtp_file) ) @@ -753,7 +753,7 @@ def get_hybrid_residues( m, mtp_file, version ): mtp = get_hybrid_residue( res.resname, mtp_file, version ) rdic[res.resname] = mtp hybrid_res = mtp[0] - atom_names = map(lambda a: a.name, hybrid_res.atoms ) + atom_names = [a.name for a in hybrid_res.atoms] atoms = res.fetchm( atom_names ) for i, atom in enumerate( hybrid_res.atoms ): atoms[i].atomtypeB = atom.atomtypeB @@ -766,13 +766,13 @@ def __add_extra_DNA_RNA_impropers( topol, rlist, func_type, stateA, stateB ): extra_impropers = [] for r in rlist: if r.resname in ['DAT','DAC','DGC','DGT','RAU','RAC','RGC','RGU']: - print 'Adding extra improper dihedrals for residue %d-%s' % (r.id, r.resname) + print('Adding extra improper dihedrals for residue %d-%s' % (r.id, r.resname)) alist = r.fetchm(['C1\'','N9','C8','DC2']) extra_impropers.append( alist ) alist = r.fetchm(['C1\'','N9','C4','DC6']) extra_impropers.append( alist ) elif r.resname in ['DTA','DTG','DCG','DCA','RUA','RUG','RCG','RCA']: - print 'Adding extra improper dihedrals for residue %d-%s' % (r.id, r.resname) + print('Adding extra improper dihedrals for residue %d-%s' % (r.id, r.resname)) alist = r.fetchm(['C1\'','N1','C6','DC4']) extra_impropers.append( alist ) alist = r.fetchm(['C1\'','N1','C2','DC8']) @@ -816,11 +816,11 @@ def get_ff_path( ff ): elif os.path.isdir(pff): ff_path = pff else: - print >>sys.stderr,' Error: forcefield path "%s" not found' % ff + print(' Error: forcefield path "%s" not found' % ff, file=sys.stderr) sys.exit(0) else: ff_path = ff - print 'Opening forcefield: %s' % ff_path + print('Opening forcefield: %s' % ff_path) return ff_path def main(argv): @@ -841,22 +841,22 @@ def main(argv): ] help_text = ('This script adds a B state to an .itp or .top file for a hybrid residue.', - 'Hybrid residues in the topology file are recognized automatically.', - '-scale_mass flag sets dummy masses to 1.0, this option is set to True by default.', - 'Currently available force fields:', - ' - amber99sbmut (Hornak et al, 2006)', - ' - amber99sb-star-ildn-mut (Best & Hummer, 2009; Lindorff-Larsen et al, 2010)', - ' - charmm22starmut.ff (Piana et al, 2011)', - ' - charmm36mut (Best et al, 2012)', - ' - oplsaamut (Jorgensen et al, 1996; Kaminski et al, 2001)', + 'Hybrid residues in the topology file are recognized automatically.', + '-scale_mass flag sets dummy masses to 1.0, this option is set to True by default.', + 'Currently available force fields:', + ' - amber99sbmut (Hornak et al, 2006)', + ' - amber99sb-star-ildn-mut (Best & Hummer, 2009; Lindorff-Larsen et al, 2010)', + ' - charmm22starmut.ff (Piana et al, 2011)', + ' - charmm36mut (Best et al, 2012)', + ' - oplsaamut (Jorgensen et al, 1996; Kaminski et al, 2001)', '', '', 'Please cite:', 'Vytautas Gapsys, Servaas Michielssens, Daniel Seeliger and Bert L. de Groot.', 'Automated Protein Structure and Topology Generation for Alchemical Perturbations.', - 'J. Comput. Chem. 2015, 36, 348-354. DOI: 10.1002/jcc.23804', + 'J. Comput. Chem. 2015, 36, 348-354. DOI: 10.1002/jcc.23804', '', - 'Old pmx (pymacs) version:', + 'Old pmx (pymacs) version:', 'Daniel Seeliger and Bert L. de Groot. Protein Thermostability Calculations Using', 'Alchemical Free Energy Simulations, Biophysical Journal, 98(10):2309-2316 (2010)', '', @@ -890,15 +890,15 @@ def main(argv): input_itp = None if input_itp and out_file.split('.')[-1] != 'itp': out_file = change_outfile_format(out_file, 'itp') - print 'log_> Setting outfile name to %s' % out_file + print('log_> Setting outfile name to %s' % out_file) if input_itp: # print 'log_> Reading input files "%s" and "%s"' % (top_file, input_itp) # topol = Topology( input_itp, topfile = top_file, version = 'new', ff = cmdl['-ff'] ) - print 'log_> Reading input .itp file "%s""' % (input_itp) + print('log_> Reading input .itp file "%s""' % (input_itp)) topol = Topology( input_itp, topfile = None, version = 'new', ff = cmdl['-ff'], ffpath=get_ff_path(cmdl['-ff']) ) else: - print 'log_> Reading input .top file "%s"' % (top_file) + print('log_> Reading input .top file "%s"' % (top_file)) topol = Topology( top_file, topfile=top_file, version = 'new', ff = cmdl['-ff'] ) # for i in topol.dihedrals: @@ -911,11 +911,11 @@ def main(argv): topol.assign_fftypes() # correct b-states # for atom in m.atoms: # print atom.type -# if atom.atomtypeB is not None: -# print "typeB" -# print atom.typeB +# if atom.atomtypeB is not None: +# print "typeB" +# print atom.typeB for r in rlist: - print 'log_> Hybrid Residue -> %d | %s ' % (r.id, r.resname ) + print('log_> Hybrid Residue -> %d | %s ' % (r.id, r.resname )) find_bonded_entries( topol ) @@ -930,8 +930,8 @@ def main(argv): qA_mem = copy.deepcopy( qA ) qB_mem = copy.deepcopy( qB ) - print 'log_> Total charge of state A = ', topol.get_qA() - print 'log_> Total charge of state B = ', topol.get_qB() + print('log_> Total charge of state A = ', topol.get_qA()) + print('log_> Total charge of state B = ', topol.get_qB()) topol.write( out_file, scale_mass = do_scale_mass, target_qB = qB ) @@ -945,34 +945,34 @@ def main(argv): out_file_vdw = root+'_vdw'+ext out_file_qon = root+'_qon'+ext - print '------------------------------------------------------' - print 'log_> Creating splitted topologies............' - print 'log_> Making "qoff" topology : "%s"' % out_file_qoff + print('------------------------------------------------------') + print('log_> Creating splitted topologies............') + print('log_> Making "qoff" topology : "%s"' % out_file_qoff) contQ = copy.deepcopy(qA_mem) topol.write( out_file_qoff, stateQ = 'AB', stateTypes = 'AA', dummy_qB='off', scale_mass = do_scale_mass, target_qB = qA, stateBonded = 'AA', full_morphe = False ) - print 'log_> Charge of state A: %g' % topol.qA - print 'log_> Charge of state B: %g' % topol.qB + print('log_> Charge of state A: %g' % topol.qA) + print('log_> Charge of state B: %g' % topol.qB) - print '------------------------------------------------------' - print 'log_> Making "vdw" topology : "%s"' % out_file_vdw + print('------------------------------------------------------') + print('log_> Making "vdw" topology : "%s"' % out_file_vdw) contQ = copy.deepcopy(qA_mem) topol.write( out_file_vdw, stateQ = 'BB', stateTypes = 'AB', dummy_qA='off', dummy_qB = 'off', scale_mass = do_scale_mass, target_qB = contQ, stateBonded = 'AB' , full_morphe = False) - print 'log_> Charge of state A: %g' % topol.qA - print 'log_> Charge of state B: %g' % topol.qB - print '------------------------------------------------------' + print('log_> Charge of state A: %g' % topol.qA) + print('log_> Charge of state B: %g' % topol.qB) + print('------------------------------------------------------') - print 'log_> Making "qon" topology : "%s"' % out_file_qon + print('log_> Making "qon" topology : "%s"' % out_file_qon) topol.write( out_file_qon, stateQ = 'BB', stateTypes = 'BB', dummy_qA='off', dummy_qB = 'on', scale_mass = do_scale_mass, target_qB = qB_mem, stateBonded = 'BB' , full_morphe = False) - print 'log_> Charge of state A: %g' % topol.qA - print 'log_> Charge of state B: %g' % topol.qB - print '------------------------------------------------------' + print('log_> Charge of state A: %g' % topol.qA) + print('log_> Charge of state B: %g' % topol.qB) + print('------------------------------------------------------') - print - print 'making b-states done...........' - print + print() + print('making b-states done...........') + print() def entry_point(): diff --git a/pmx/scripts/ligands/atoms_to_morph.py b/pmx/scripts/ligands/atoms_to_morph.py index 98529f0d..52485dea 100755 --- a/pmx/scripts/ligands/atoms_to_morph.py +++ b/pmx/scripts/ligands/atoms_to_morph.py @@ -26,12 +26,12 @@ def alignOnSubset(mol1,mol2,constrMap): # only heavy atoms can be constraints rem = [] for c in constrMap: - a1 = mol1.GetAtomWithIdx(c[0]) - a2 = mol2.GetAtomWithIdx(c[1]) + a1 = mol1.GetAtomWithIdx(c[0]) + a2 = mol2.GetAtomWithIdx(c[1]) id1 = a1.GetAtomicNum() id2 = a2.GetAtomicNum() if((id1==1) or (id2==1)): - rem.append(c) + rem.append(c) # remove for i in rem: constrMap.remove(i) @@ -47,43 +47,43 @@ def getAttr(n1,n2,iStart,iEnd): jStart = None jEnd = None for foo,bar in zip(n1,n2): - if(foo==iStart): - jStart = bar - if(foo==iEnd): - jEnd = bar + if(foo==iStart): + jStart = bar + if(foo==iEnd): + jEnd = bar return(jStart,jEnd) def getMapped(n1,n2,ind1): ind2 = None for id1,id2 in zip(n1,n2): - if id1==ind1: - ind2=id2 - return(ind2) + if id1==ind1: + ind2=id2 + return(ind2) return(ind2) def getMappedList(n1,n2,indList1): indList2 = [] for ind1 in indList1: for id1,id2 in zip(n1,n2): - if id1==ind1: - indList2.append(id2) - break + if id1==ind1: + indList2.append(id2) + break return(indList2) def checkNeighDist(mol1,mol2,nb1,n1,n2,rem1,rem2): c1 = mol1.GetConformer() c2 = mol2.GetConformer() for neigh1 in nb1: - ind1 = neigh1.GetIdx() - if ind1 in n1: - ind2 = getMapped(n1,n2,ind1) - if ind2!=None: - dist = distance_based(mol1,mol2,0.0,id1=[ind1],id2=[ind2],calcOnly=True) -# print ind1,ind2,dist - if dist > 0.15: # 0.15 nm distance should be forgiving enough, but also catch the cases of chirality inversions - if (ind1 not in rem1) and (ind2 not in rem2): - rem1.append(ind1) - rem2.append(ind2) + ind1 = neigh1.GetIdx() + if ind1 in n1: + ind2 = getMapped(n1,n2,ind1) + if ind2!=None: + dist = distance_based(mol1,mol2,0.0,id1=[ind1],id2=[ind2],calcOnly=True) +# print ind1,ind2,dist + if dist > 0.15: # 0.15 nm distance should be forgiving enough, but also catch the cases of chirality inversions + if (ind1 not in rem1) and (ind2 not in rem2): + rem1.append(ind1) + rem2.append(ind2) def localEnvironment(mol,i,n): a1 = mol.GetAtomWithIdx(i) @@ -92,14 +92,14 @@ def localEnvironment(mol,i,n): list12 = [] list13 = [] for a2 in nb1: - ind1 = a2.GetIdx() - if ind1 in n: - list12.append(ind1) + ind1 = a2.GetIdx() + if ind1 in n: + list12.append(ind1) nb2 = a2.GetNeighbors() - for a3 in nb2: - ind2 = a3.GetIdx() - if (ind2 in n) and (ind2 not in list12) and (ind2 not in list13) and (ind2 != i): - list13.append(ind2) + for a3 in nb2: + ind2 = a3.GetIdx() + if (ind2 in n) and (ind2 not in list12) and (ind2 not in list13) and (ind2 != i): + list13.append(ind2) # final list listFinal = [i] + list12 + list13 return(listFinal) @@ -107,9 +107,9 @@ def localEnvironment(mol,i,n): def checkChiral(mol1,mol2,n1,n2): # create constraint for alignment - constrMap = zip(n1,n2) + constrMap = list(zip(n1,n2)) # align on the subset n1,n2 - Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(n2,n1)) + Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=list(zip(n2,n1))) bonds1 = mol1.GetBonds() bonds2 = mol2.GetBonds() # create two dictionaries for mappings [n1] = n2 @@ -129,29 +129,29 @@ def checkChiral(mol1,mol2,n1,n2): bNonsingleBond1 = check_nonsingle_bonds( mol1, mol2, bonds1, n1, n2, dictn1n2 ) bNonsingleBond2 = check_nonsingle_bonds( mol2, mol1, bonds2, n2, n1, dictn2n1 ) if (str(chirality1) != "CHI_UNSPECIFIED") or (bNonsingleBond1==True): -# print "1",i1,chirality1 - # try fitting locally on the 1-2, 1-3 atoms - localEnv1 = localEnvironment(mol1,i1,n1) - if len(localEnv1)>2: - localEnv2 = getMappedList(n1,n2,localEnv1) - Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(localEnv2,localEnv1)) -# alignOnSubset(mol1,mol2,zip(localEnv1,localEnv2)) - # get the neighbours - nb1 = a1.GetNeighbors() - # check if the matched neighbours in the aligned molecules are too far - checkNeighDist(mol1,mol2,nb1,n1,n2,rem1,rem2) +# print "1",i1,chirality1 + # try fitting locally on the 1-2, 1-3 atoms + localEnv1 = localEnvironment(mol1,i1,n1) + if len(localEnv1)>2: + localEnv2 = getMappedList(n1,n2,localEnv1) + Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=list(zip(localEnv2,localEnv1))) +# alignOnSubset(mol1,mol2,zip(localEnv1,localEnv2)) + # get the neighbours + nb1 = a1.GetNeighbors() + # check if the matched neighbours in the aligned molecules are too far + checkNeighDist(mol1,mol2,nb1,n1,n2,rem1,rem2) if (str(chirality2) != "CHI_UNSPECIFIED") or (bNonsingleBond2==True): -# print "2",i2,chirality2 +# print "2",i2,chirality2 # try fitting locally on the 1-2, 1-3 atoms localEnv2 = localEnvironment(mol2,i2,n2) if len(localEnv2)>2: localEnv1 = getMappedList(n2,n1,localEnv2) - Chem.rdMolAlign.AlignMol(mol1,mol2,atomMap=zip(localEnv1,localEnv2)) + Chem.rdMolAlign.AlignMol(mol1,mol2,atomMap=list(zip(localEnv1,localEnv2))) # alignOnSubset(mol1,mol2,zip(localEnv1,localEnv2)) # get the neighbours nb2 = a2.GetNeighbors() # check if the matched neighbours in the aligned molecules are too far - checkNeighDist(mol2,mol1,nb2,n2,n1,rem2,rem1) + checkNeighDist(mol2,mol1,nb2,n2,n1,rem2,rem1) ####### remove ####### n1_out = [] @@ -170,9 +170,9 @@ def bCheckChiralViolation(mol1,mol2,n1,n2): if len(n1)<2 and len(n2)<2: return(bViolation) # create constraint for alignment - constrMap = zip(n1,n2) + constrMap = list(zip(n1,n2)) # align on the subset n1,n2 - Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(n2,n1)) + Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=list(zip(n2,n1))) rem1 = [] rem2 = [] bonds1 = mol1.GetBonds() @@ -180,7 +180,7 @@ def bCheckChiralViolation(mol1,mol2,n1,n2): # create two dictionaries for mappings [n1] = n2 dictn1n2 = mappingDict( n1,n2 ) dictn2n1 = mappingDict( n2,n1 ) - + for i1,i2 in zip(n1,n2): a1 = mol1.GetAtomWithIdx(i1) a2 = mol2.GetAtomWithIdx(i2) @@ -195,26 +195,26 @@ def bCheckChiralViolation(mol1,mol2,n1,n2): # print bNonsingleBond1 # bonds_a1 = find_atom_bonds( i1, a1, bonds1 ) # find all bonds in which a1 takes part # sys.exit(0) - if (str(chirality1) != "CHI_UNSPECIFIED") or (bNonsingleBond1==True): -# print "1check",i1,chirality1 + if (str(chirality1) != "CHI_UNSPECIFIED") or (bNonsingleBond1==True): +# print "1check",i1,chirality1 localEnv1 = localEnvironment(mol1,i1,n1) if len(localEnv1)>2: localEnv2 = getMappedList(n1,n2,localEnv1) - Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(localEnv2,localEnv1)) + Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=list(zip(localEnv2,localEnv1))) #alignOnSubset(mol1,mol2,zip(localEnv1,localEnv2)) nb1 = a1.GetNeighbors() checkNeighDist(mol1,mol2,nb1,n1,n2,rem1,rem2) - if (str(chirality2) != "CHI_UNSPECIFIED") or (bNonsingleBond2==True): -# print "2check",i2,chirality2 + if (str(chirality2) != "CHI_UNSPECIFIED") or (bNonsingleBond2==True): +# print "2check",i2,chirality2 localEnv2 = localEnvironment(mol2,i2,n2) if len(localEnv2)>2: localEnv1 = getMappedList(n2,n1,localEnv2) - Chem.rdMolAlign.AlignMol(mol1,mol2,atomMap=zip(localEnv1,localEnv2)) + Chem.rdMolAlign.AlignMol(mol1,mol2,atomMap=list(zip(localEnv1,localEnv2))) #alignOnSubset(mol1,mol2,zip(localEnv1,localEnv2)) nb2 = a2.GetNeighbors() checkNeighDist(mol2,mol1,nb2,n2,n1,rem2,rem1) - if len(rem1)+len(rem2)>0: - return(True) + if len(rem1)+len(rem2)>0: + return(True) return(bViolation) # bond length table @@ -273,22 +273,22 @@ def checkTopRemove(mol1,mol2,n1,n2,startList,endList): rem1 = [] rem2 = [] for iStart,iEnd in zip(startList,endList): - jStart,jEnd = getAttr(n1,n2,iStart,iEnd) - # count iStart mapped neighbours - startNeighb = 0 - for b1 in mol1.GetBonds(): + jStart,jEnd = getAttr(n1,n2,iStart,iEnd) + # count iStart mapped neighbours + startNeighb = 0 + for b1 in mol1.GetBonds(): foo = b1.GetBeginAtomIdx() bar = b1.GetEndAtomIdx() - if( iStart==foo ): # atom of interest - a,b = getAttr(n1,n2,iStart,bar) - if( (a!=None) and (b!=None) ): - startNeighb = startNeighb+1 - elif( iStart==bar ): # atom of interest + if( iStart==foo ): # atom of interest + a,b = getAttr(n1,n2,iStart,bar) + if( (a!=None) and (b!=None) ): + startNeighb = startNeighb+1 + elif( iStart==bar ): # atom of interest a,b = getAttr(n1,n2,iStart,foo) if( (a!=None) and (b!=None) ): startNeighb = startNeighb+1 - # count iEnd mapped neighbour - endNeighb = 0 + # count iEnd mapped neighbour + endNeighb = 0 for b1 in mol1.GetBonds(): foo = b1.GetBeginAtomIdx() bar = b1.GetEndAtomIdx() @@ -296,122 +296,122 @@ def checkTopRemove(mol1,mol2,n1,n2,startList,endList): a,b = getAttr(n1,n2,iEnd,bar) if( (a!=None) and (b!=None) ): endNeighb = endNeighb+1 - elif( iEnd==bar ): # atom of interest + elif( iEnd==bar ): # atom of interest a,b = getAttr(n1,n2,iEnd,foo) if( (a!=None) and (b!=None) ): endNeighb = endNeighb+1 - # add to remove list - if( startNeighb < endNeighb ): - rem1.append(iStart) - rem2.append(jStart) - else: - rem1.append(iEnd) - rem2.append(jEnd) + # add to remove list + if( startNeighb < endNeighb ): + rem1.append(iStart) + rem2.append(jStart) + else: + rem1.append(iEnd) + rem2.append(jEnd) # remove for i,j in zip(rem1,rem2): - n1.remove(i) - n2.remove(j) + n1.remove(i) + n2.remove(j) return(n1,n2) def getList12(mol,n): dict12 = {} for a1 in mol.GetAtoms(): - iStart1 = a1.GetIdx() - if iStart1 not in n: - continue - neighbours1 = a1.GetNeighbors() - for a2 in neighbours1: # 1-2 - iEnd2 = a2.GetIdx() - if iEnd2 not in n: - continue - if iEnd2 == iStart1: - continue - if iStart1 in dict12.keys(): + iStart1 = a1.GetIdx() + if iStart1 not in n: + continue + neighbours1 = a1.GetNeighbors() + for a2 in neighbours1: # 1-2 + iEnd2 = a2.GetIdx() + if iEnd2 not in n: + continue + if iEnd2 == iStart1: + continue + if iStart1 in list(dict12.keys()): if iEnd2 not in dict12[iStart1]: - dict12[iStart1].append(iEnd2) - else: - dict12[iStart1] = [iEnd2] + dict12[iStart1].append(iEnd2) + else: + dict12[iStart1] = [iEnd2] return(dict12) def getList13(mol,n): dict13 = {} for a1 in mol.GetAtoms(): - iStart1 = a1.GetIdx() + iStart1 = a1.GetIdx() if iStart1 not in n: continue - neighbours1 = a1.GetNeighbors() - for a2 in neighbours1: # 1-2 - i2 = a2.GetIdx() + neighbours1 = a1.GetNeighbors() + for a2 in neighbours1: # 1-2 + i2 = a2.GetIdx() # if i2 not in n: # continue - if i2 == iStart1: - continue - neighbours2 = a2.GetNeighbors() - for a3 in neighbours2: # 1-3 - iEnd3 = a3.GetIdx() - if iEnd3 not in n: - continue - if (iEnd3==iStart1) or (iEnd3==i2): - continue - if iStart1 in dict13.keys(): + if i2 == iStart1: + continue + neighbours2 = a2.GetNeighbors() + for a3 in neighbours2: # 1-3 + iEnd3 = a3.GetIdx() + if iEnd3 not in n: + continue + if (iEnd3==iStart1) or (iEnd3==i2): + continue + if iStart1 in list(dict13.keys()): if iEnd3 not in dict13[iStart1]: - dict13[iStart1].append(iEnd3) - else: - dict13[iStart1] = [iEnd3] + dict13[iStart1].append(iEnd3) + else: + dict13[iStart1] = [iEnd3] return(dict13) def getList14(mol,n): dict14 = {} for a1 in mol.GetAtoms(): - iStart1 = a1.GetIdx() + iStart1 = a1.GetIdx() if iStart1 not in n: continue - neighbours1 = a1.GetNeighbors() - for a2 in neighbours1: # 1-2 - i2 = a2.GetIdx() + neighbours1 = a1.GetNeighbors() + for a2 in neighbours1: # 1-2 + i2 = a2.GetIdx() # if i2 not in n: # continue - if i2 == iStart1: - continue - neighbours2 = a2.GetNeighbors() - for a3 in neighbours2: # 1-3 - i3 = a3.GetIdx() -# if i3 not in n: -# continue - if (i3==iStart1) or (i3==i2): - continue + if i2 == iStart1: + continue + neighbours2 = a2.GetNeighbors() + for a3 in neighbours2: # 1-3 + i3 = a3.GetIdx() +# if i3 not in n: +# continue + if (i3==iStart1) or (i3==i2): + continue neighbours3 = a3.GetNeighbors() for a4 in neighbours3: # 1-4 iEnd4 = a4.GetIdx() - if iEnd4 not in n: - continue + if iEnd4 not in n: + continue if (iEnd4==iStart1) or (iEnd4==i2) or (iEnd4==i3): continue - if iStart1 in dict14.keys(): + if iStart1 in list(dict14.keys()): if iEnd4 not in dict14[iStart1]: - dict14[iStart1].append(iEnd4) - else: - dict14[iStart1] = [iEnd4] + dict14[iStart1].append(iEnd4) + else: + dict14[iStart1] = [iEnd4] return(dict14) def findProblemsExclusions(n1,n2,dict_mol1,dict_mol2): rem_start = [] rem_end = [] - for iStart in dict_mol1.keys(): - for iEnd in dict_mol1[iStart]: - jStart,jEnd = getAttr(n1,n2,iStart,iEnd) - if( (jStart==None) or (jEnd==None) ): # mapped to a dummy, thus no worries - continue - if jStart in dict_mol2.keys(): - if jEnd not in dict_mol2[jStart]: - # maybe entry already exists - if ((jStart in rem_start) or (jStart in rem_end)) and ((jEnd in rem_start) or (jEnd in rem_end)): - continue - rem_start.append(jStart) - rem_end.append(jEnd) - elif jEnd not in dict_mol2.keys(): - # a weird situation that shouldn't happen - print "Warning: something wrong in the 1-2, 1-3 or 1-4 lists. Trying to proceed with the warning..." + for iStart in list(dict_mol1.keys()): + for iEnd in dict_mol1[iStart]: + jStart,jEnd = getAttr(n1,n2,iStart,iEnd) + if( (jStart==None) or (jEnd==None) ): # mapped to a dummy, thus no worries + continue + if jStart in list(dict_mol2.keys()): + if jEnd not in dict_mol2[jStart]: + # maybe entry already exists + if ((jStart in rem_start) or (jStart in rem_end)) and ((jEnd in rem_start) or (jEnd in rem_end)): + continue + rem_start.append(jStart) + rem_end.append(jEnd) + elif jEnd not in list(dict_mol2.keys()): + # a weird situation that shouldn't happen + print("Warning: something wrong in the 1-2, 1-3 or 1-4 lists. Trying to proceed with the warning...") rem_start.append(jStart) rem_end.append(jEnd) return(rem_start,rem_end) @@ -443,7 +443,7 @@ def fixProblemsExclusions(mol1,mol2,n1,n2,startList,endList): a,b = getAttr(n1,n2,iEnd,bar) if( (a!=None) and (b!=None) ): endNeighb = endNeighb+1 - elif( iEnd==bar ): # atom of interest + elif( iEnd==bar ): # atom of interest a,b = getAttr(n1,n2,iEnd,foo) if( (a!=None) and (b!=None) ): endNeighb = endNeighb+1 @@ -469,18 +469,18 @@ def checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy): # 2) identify problematic mappings # 3) fix the problems: discard the atom with fewer mapped neighbours - ####### 1-2 ######### + ####### 1-2 ######### # 1a) 1-2 lists dict12_mol1 = getList12(mol1,n1) dict12_mol2 = getList12(mol2,n2) - # 2a) identify problems 1-2; and + # 2a) identify problems 1-2; and # 3a) fix 1-2 rem12_mol2_start,rem12_mol2_end = findProblemsExclusions(n1,n2,dict12_mol1,dict12_mol2) # output: indeces of mol2 n2,n1 = fixProblemsExclusions(mol2,mol1,n2,n1,rem12_mol2_start,rem12_mol2_end) rem12_mol1_start,rem12_mol1_end = findProblemsExclusions(n2,n1,dict12_mol2,dict12_mol1) # output: indeces of mol1 n1,n2 = fixProblemsExclusions(mol1,mol2,n1,n2,rem12_mol1_start,rem12_mol1_end) - ####### 1-3 ######### + ####### 1-3 ######### # 1b) 1-3 lists dict13_mol1 = getList13(mol1,n1) dict13_mol2 = getList13(mol2,n2) @@ -491,11 +491,11 @@ def checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy): rem13_mol1_start,rem13_mol1_end = findProblemsExclusions(n2,n1,dict13_mol2,dict13_mol1) # output: indeces of mol1 n1,n2 = fixProblemsExclusions(mol1,mol2,n1,n2,rem13_mol1_start,rem13_mol1_end) - ####### 1-4 ######### + ####### 1-4 ######### # 1b) 1-4 lists dict14_mol1 = getList14(mol1,n1) dict14_mol2 = getList14(mol2,n2) - # 2b) identify problems 1-4 and + # 2b) identify problems 1-4 and # 3b) fix 1-4 rem14_mol2_start,rem14_mol2_end = findProblemsExclusions(n1,n2,dict14_mol1,dict14_mol2) # output: indeces of mol2 n2,n1 = fixProblemsExclusions(mol2,mol1,n2,n1,rem14_mol2_start,rem14_mol2_end) @@ -511,29 +511,29 @@ def checkMCSTop(mol1,mol2,n1,n2,bH2H,bH2heavy): # if a bond exists in only one substructure, # modify the mapping by discarding one atom participating in the unmatched bond # try to discard the atom with fewer mapped neighbours - + # mol1 bonds startList = [] endList = [] for b1 in mol1.GetBonds(): iStart = b1.GetBeginAtomIdx() iEnd = b1.GetEndAtomIdx() - jStart,jEnd = getAttr(n1,n2,iStart,iEnd) - if( (jStart!=None) and (jEnd!=None) ): # not dummies - bOk = False - for b2 in mol2.GetBonds(): - foo = b2.GetBeginAtomIdx() - bar = b2.GetEndAtomIdx() - if( foo==jStart and bar==jEnd ): - bOk = True - break - elif( foo==jEnd and bar==jStart ): - bOk = True - break - if(bOk == False): - startList.append(iStart) - endList.append(iEnd) -# return(bOk) + jStart,jEnd = getAttr(n1,n2,iStart,iEnd) + if( (jStart!=None) and (jEnd!=None) ): # not dummies + bOk = False + for b2 in mol2.GetBonds(): + foo = b2.GetBeginAtomIdx() + bar = b2.GetEndAtomIdx() + if( foo==jStart and bar==jEnd ): + bOk = True + break + elif( foo==jEnd and bar==jStart ): + bOk = True + break + if(bOk == False): + startList.append(iStart) + endList.append(iEnd) +# return(bOk) n1,n2 = checkTopRemove(mol1,mol2,n1,n2,startList,endList,bH2H,bH2heavy) # mol2 bonds @@ -544,7 +544,7 @@ def checkMCSTop(mol1,mol2,n1,n2,bH2H,bH2heavy): iEnd = b1.GetEndAtomIdx() jStart,jEnd = getAttr(n2,n1,iStart,iEnd) if( (jStart!=None) and (jEnd!=None) ): # not dummies - bOk = False + bOk = False for b2 in mol1.GetBonds(): foo = b2.GetBeginAtomIdx() bar = b2.GetEndAtomIdx() @@ -554,10 +554,10 @@ def checkMCSTop(mol1,mol2,n1,n2,bH2H,bH2heavy): elif( foo==jEnd and bar==jStart ): bOk = True break - if(bOk == False): + if(bOk == False): startList.append(iStart) endList.append(iEnd) -# return(bOk) +# return(bOk) n1,n2 = checkTopRemove(mol2,mol1,n2,n1,startList,endList) return(True) @@ -565,22 +565,22 @@ def checkMCSTop(mol1,mol2,n1,n2,bH2H,bH2heavy): def writeFormatPDB(fname,m,title="",nr=1): fp = open(fname,'w') for atom in m.atoms: - foo = cp.deepcopy(atom) - # chlorine - if( 'CL' in atom.name or 'Cl' in atom.name or 'cl' in atom.name ): - foo.name = "Cl"#+" " - print >>fp, foo - # bromine + foo = cp.deepcopy(atom) + # chlorine + if( 'CL' in atom.name or 'Cl' in atom.name or 'cl' in atom.name ): + foo.name = "Cl"#+" " + print(foo, file=fp) + # bromine elif( 'BR' in atom.name or 'Br' in atom.name or 'br' in atom.name ): foo.name = "Br"#+" " - print >>fp, foo + print(foo, file=fp) elif( len(atom.name) >= 4): # too long atom name foo = cp.deepcopy(atom) foo.name = foo.name[:3] - print >>fp, foo + print(foo, file=fp) else: - print >>fp, atom - print >>fp, 'ENDMDL' + print(atom, file=fp) + print('ENDMDL', file=fp) fp.close() # sys.exit(0) @@ -605,7 +605,7 @@ def reformatPDB(filename,num,randint=42): return(newname,atomNameID,sigmaHoleID) def restoreAtomNames(mol,atomNameID): - + for atom in mol.GetAtoms(): newname = atom.GetMonomerInfo().GetName() ind = atom.GetIdx()+1 @@ -618,10 +618,10 @@ def restoreAtomNames(mol,atomNameID): def write_pairs(n1,n2,pairsFilename): fp = open(pairsFilename,"w") for i1,i2 in zip(n1,n2): - foo = i1 + 1 - bar = i2 + 1 - fp.write("%s %s\n" % (foo,bar) ) - fp.close() + foo = i1 + 1 + bar = i2 + 1 + fp.write("%s %s\n" % (foo,bar) ) + fp.close() def calcScore(mol1,mol2,n1,n2,bH2H,bH2heavy): res = 0.0 @@ -629,11 +629,11 @@ def calcScore(mol1,mol2,n1,n2,bH2H,bH2heavy): nn2 = len(n2) res = (nn1+nn2)/2.0 if( bH2H==True or bH2heavy==True): # consider hydrogens - na1 = mol1.GetNumAtoms() - na2 = mol2.GetNumAtoms() + na1 = mol1.GetNumAtoms() + na2 = mol2.GetNumAtoms() else: # no hydrogens - na1 = mol1.GetNumHeavyAtoms() - na2 = mol2.GetNumHeavyAtoms() + na1 = mol1.GetNumHeavyAtoms() + na2 = mol2.GetNumHeavyAtoms() res = 1.0 - res/(na1+na2-res) return(res) @@ -643,25 +643,25 @@ def distance_based(mol1, mol2, d, id1=None, id2=None, calcOnly=False): # to choose one MCS out of many if(calcOnly==True): - dist = 0.0 + dist = 0.0 c1 = mol1.GetConformer() c2 = mol2.GetConformer() for ind1,ind2 in zip(id1,id2): pos1 = c1.GetAtomPosition(ind1) pos2 = c2.GetAtomPosition(ind2) - dist = dist + 0.1*pos1.Distance(pos2) # Angstroms in pdb files + dist = dist + 0.1*pos1.Distance(pos2) # Angstroms in pdb files return(dist) # o3a if(id1==None or id2==None): c1 = mol1.GetConformer() c2 = mol2.GetConformer() - for a1 in mol1.GetAtoms(): + for a1 in mol1.GetAtoms(): pos1 = c1.GetAtomPosition(a1.GetIdx()) - dd = d*10.0 # Angstroms in pdb files + dd = d*10.0 # Angstroms in pdb files keep1 = None keep2 = None - for a2 in mol2.GetAtoms(): + for a2 in mol2.GetAtoms(): pos2 = c2.GetAtomPosition(a2.GetIdx()) dist = pos1.Distance(pos2) if(dist < dd): @@ -670,27 +670,27 @@ def distance_based(mol1, mol2, d, id1=None, id2=None, calcOnly=False): keep2 = a2.GetIdx() if( (keep1 is not None) and (keep2 is not None) ): pairs1.append(keep1) - pairs2.append(keep2) - return(pairs1,pairs2) + pairs2.append(keep2) + return(pairs1,pairs2) # mcs for ind1 in id1: - c1 = mol1.GetConformer() - pos1 = c1.GetAtomPosition(ind1) - dd = d*10.0 # Angstroms in pdb files - keep1 = None - keep2 = None - for ind2 in id2: - c2 = mol2.GetConformer() - pos2 = c2.GetAtomPosition(ind2) - dist = pos1.Distance(pos2) - if(dist < dd): - dd = dist - keep1 = ind1 - keep2 = ind2 - if( (keep1 is not None) and (keep2 is not None) ): - pairs1.append(keep1) - pairs2.append(keep2) + c1 = mol1.GetConformer() + pos1 = c1.GetAtomPosition(ind1) + dd = d*10.0 # Angstroms in pdb files + keep1 = None + keep2 = None + for ind2 in id2: + c2 = mol2.GetConformer() + pos2 = c2.GetAtomPosition(ind2) + dist = pos1.Distance(pos2) + if(dist < dd): + dd = dist + keep1 = ind1 + keep2 = ind2 + if( (keep1 is not None) and (keep2 is not None) ): + pairs1.append(keep1) + pairs2.append(keep2) return(pairs1,pairs2) def chargesTypesMMFF(mol): @@ -708,8 +708,8 @@ def o3a_alignment(mol1, mol2, bH2H, bH2Hpolar, bH2heavy, bRingsOnly, sigmaHoleID # prepare molecules and parameters # #################################### if( bRingsOnly==True ): - submol1 = subMolRing(mol1) - submol2 = subMolRing(mol2) + submol1 = subMolRing(mol1) + submol2 = subMolRing(mol2) ################### #### now align #### ################### @@ -742,11 +742,11 @@ def o3a_alignment(mol1, mol2, bH2H, bH2Hpolar, bH2heavy, bRingsOnly, sigmaHoleID n1,n2 = matchRings(mol1,mol2,n1,n2) # checking possible issues with the 1-2, 1-3 and 1-4 interactions # this is done before the ringCheck and repeated after - n1,n2 = checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy) + n1,n2 = checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy) # do not break rings bBreakRings = False if( bBreakRings==False ): - print "Avoiding breaking rings.\n" + print("Avoiding breaking rings.\n") n1,n2 = matchFullRings(mol1,mol2,n1,n2) # sys.exit(0) # treat disconnected @@ -755,7 +755,7 @@ def o3a_alignment(mol1, mol2, bH2H, bH2Hpolar, bH2heavy, bRingsOnly, sigmaHoleID # n1 and n2 are not sorted by pairs at this point n1,n2 = sortInd(mol1,mol2,n1,n2) # checking possible issues with the 1-2, 1-3 and 1-4 interactions - n1,n2 = checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy) + n1,n2 = checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy) return(n1,n2,pyO3A) @@ -768,12 +768,12 @@ def matchRings(mol1,mol2,nfoo,nbar): a2 = mol2.GetAtomWithIdx(n2) # arom1 = a1.GetIsAromatic() # arom2 = a2.GetIsAromatic() - ring1 = a1.IsInRing() - ring2 = a2.IsInRing() - if(ring1==True and ring2==False): - continue - if(ring1==False and ring2==True): - continue + ring1 = a1.IsInRing() + ring2 = a2.IsInRing() + if(ring1==True and ring2==False): + continue + if(ring1==False and ring2==True): + continue newn1.append(n1) newn2.append(n2) @@ -785,61 +785,61 @@ def oneAtomInRing(mol1,mol2,n1,n2): newn1 = [] newn2 = [] for i,j in zip(n1,n2): - a1 = mol1.GetAtomWithIdx(i) - a2 = mol2.GetAtomWithIdx(j) + a1 = mol1.GetAtomWithIdx(i) + a2 = mol2.GetAtomWithIdx(j) ring1 = a1.IsInRing() ring2 = a2.IsInRing() - if( ring1==True and ring2==True ): - bonds1 = a1.GetBonds() - bonds2 = a2.GetBonds() - found = 0 - for b1 in bonds1: - id1 = b1.GetEndAtomIdx() - at1 = b1.GetEndAtom() - if( b1.GetEndAtomIdx()==i ): - id1 = b1.GetBeginAtomIdx() - at1 = b1.GetBeginAtom() - for b2 in bonds2: + if( ring1==True and ring2==True ): + bonds1 = a1.GetBonds() + bonds2 = a2.GetBonds() + found = 0 + for b1 in bonds1: + id1 = b1.GetEndAtomIdx() + at1 = b1.GetEndAtom() + if( b1.GetEndAtomIdx()==i ): + id1 = b1.GetBeginAtomIdx() + at1 = b1.GetBeginAtom() + for b2 in bonds2: id2 = b2.GetEndAtomIdx() at2 = b2.GetEndAtom() if( b2.GetEndAtomIdx()==j ): id2 = b2.GetBeginAtomIdx() at2 = b2.GetBeginAtom() - if(at1.IsInRing()==True and at2.IsInRing()==True): - if( (id1 in n1) and (id2 in n2) ): - found = 1 - break - if(found==1): - break - if(found==1): - newn1.append(i) - newn2.append(j) - else: - newn1.append(i) - newn2.append(j) + if(at1.IsInRing()==True and at2.IsInRing()==True): + if( (id1 in n1) and (id2 in n2) ): + found = 1 + break + if(found==1): + break + if(found==1): + newn1.append(i) + newn2.append(j) + else: + newn1.append(i) + newn2.append(j) return(newn1,newn2) def carbonize(mol, bH2heavy=False, bRingsOnly=None): for atom in mol.GetAtoms(): - if(atom.GetAtomicNum() != 1): - atom.SetAtomicNum(6) - elif(bH2heavy == True): - atom.SetAtomicNum(6) - if( (bRingsOnly!=None) and (atom.IsInRing()==False) ): - atom.SetAtomicNum(bRingsOnly) + if(atom.GetAtomicNum() != 1): + atom.SetAtomicNum(6) + elif(bH2heavy == True): + atom.SetAtomicNum(6) + if( (bRingsOnly!=None) and (atom.IsInRing()==False) ): + atom.SetAtomicNum(bRingsOnly) def carbonizeCrippen(mol, bH2heavy=False, bRingsOnly=None): crippen = [] for atom in mol.GetAtoms(): if(atom.GetAtomicNum() != 1): - foo = (0.1441,2.503) + foo = (0.1441,2.503) crippen.append(foo) elif(bH2heavy == True): foo = (0.1441,2.503) crippen.append(foo) if( (bRingsOnly!=None) and (atom.IsInRing()==False) ): foo = (bRingsOnly*(-1),bRingsOnly) - crippen.append(foo) + crippen.append(foo) return(crippen) def getBondLength(mol,id1,id2): @@ -854,19 +854,19 @@ def isTriple(mol,a): # analyze C,N (S not considered, because somewhat exotic) atoms for triple bonds # C if( a.GetAtomicNum()==6 ): - if( len(a.GetNeighbors())==2 ): - for neighb in a.GetNeighbors(): - if( neighb.GetAtomicNum()==7 ): - if( len(neighb.GetNeighbors())==1 ): - bTriple=True - if( neighb.GetAtomicNum()==6 ): - if( len(neighb.GetNeighbors())==2 ): - if( getBondLength(mol,a.GetIdx(),neighb.GetIdx())<1.25 ): # need to check bond length (in Angstroms) - bTriple=True + if( len(a.GetNeighbors())==2 ): + for neighb in a.GetNeighbors(): + if( neighb.GetAtomicNum()==7 ): + if( len(neighb.GetNeighbors())==1 ): + bTriple=True + if( neighb.GetAtomicNum()==6 ): + if( len(neighb.GetNeighbors())==2 ): + if( getBondLength(mol,a.GetIdx(),neighb.GetIdx())<1.25 ): # need to check bond length (in Angstroms) + bTriple=True # N elif( a.GetAtomicNum()==7 ): - if( len(a.GetNeighbors())==1 ): - bTriple=True + if( len(a.GetNeighbors())==1 ): + bTriple=True # Chem.MolToMolFile(mol1,"foomol.mol") # foo = Chem.MolFromMolFile("foomol.mol") @@ -896,14 +896,14 @@ def removePolarHmappings(mol1,mol2,nfoo,nbar,bH2Hpolar): a2 = mol2.GetAtomWithIdx(n2) anum1 = a1.GetAtomicNum() anum2 = a2.GetAtomicNum() - + # remove polar H mappings bPolar1 = False bPolar2 = False if anum1==1: bPolar1 = isPolarH( a1 ) if anum2==1: - bPolar2 = isPolarH( a2 ) + bPolar2 = isPolarH( a2 ) if(bPolar1==True or bPolar2==True): continue @@ -920,11 +920,11 @@ def tripleBond(mol1,mol2,nfoo,nbar): for n1,n2 in zip(nfoo,nbar): a1 = mol1.GetAtomWithIdx(n1) a2 = mol2.GetAtomWithIdx(n2) - bTriple1 = False - bTriple2 = False - # identify if bTriple is True/False - bTriple1 = isTriple(mol1,a1) - bTriple2 = isTriple(mol2,a2) + bTriple1 = False + bTriple2 = False + # identify if bTriple is True/False + bTriple1 = isTriple(mol1,a1) + bTriple2 = isTriple(mol2,a2) if(bTriple1==True and bTriple2==False): continue elif(bTriple2==True and bTriple1==False): @@ -935,15 +935,15 @@ def tripleBond(mol1,mol2,nfoo,nbar): def removeH(mol1,mol2,nfoo,nbar,bH2H,bH2Hpolar,bH2heavy): newn1 = [] - newn2 = [] + newn2 = [] for n1,n2 in zip(nfoo,nbar): - a1 = mol1.GetAtomWithIdx(n1) - a2 = mol2.GetAtomWithIdx(n2) - id1 = a1.GetAtomicNum() - id2 = a2.GetAtomicNum() + a1 = mol1.GetAtomWithIdx(n1) + a2 = mol2.GetAtomWithIdx(n2) + id1 = a1.GetAtomicNum() + id2 = a2.GetAtomicNum() bPolar1 = False bPolar2 = False - if( id1==1 and id2==1): + if( id1==1 and id2==1): bPolar1 = isPolarH( a1 ) bPolar2 = isPolarH( a2 ) if(bPolar1==True and bPolar2==True): @@ -951,10 +951,10 @@ def removeH(mol1,mol2,nfoo,nbar,bH2H,bH2Hpolar,bH2heavy): continue elif( bH2H==False ): continue - elif(bH2heavy==False and ( (id1==1) ^ (id2==1) ) ): # ^ := xor - continue - newn1.append(n1) - newn2.append(n2) + elif(bH2heavy==False and ( (id1==1) ^ (id2==1) ) ): # ^ := xor + continue + newn1.append(n1) + newn2.append(n2) return(newn1,newn2) def subMolByIndex(mol,ind): @@ -997,13 +997,13 @@ def calcRMSD(mol1,mol2,ind1,ind2): c1 = mol1.GetConformer() c2 = mol2.GetConformer() for id1 in ind1: - pos1 = c1.GetAtomPosition(id1) - toAdd = 999.999 - for id2 in ind2: - pos2 = c2.GetAtomPosition(id2) - if(pos1.Distance(pos2)1: - print "WARNING: the mapping may (but not necessarily) contain disconnected fragments. Proceed with caution." - return(ind1,ind2) -# return(n1_orig,n2_orig) + if len(ind1)>1: + print("WARNING: the mapping may (but not necessarily) contain disconnected fragments. Proceed with caution.") + return(ind1,ind2) +# return(n1_orig,n2_orig) n1_list = pp.GetMatches(subMol1) n2_list = pp.GetMatches(subMol2) # remove all matched hydrogens accordingly @@ -1046,12 +1046,12 @@ def disconnectedMCS(mol1,mol2,ind1,ind2,bH2H=True,bH2Hpolar=True,bH2heavy=True): # find out which of the generated list pairs has the smallest rmsd minRMSD = 999999.99 for nl1 in n1_list: - for nl2 in n2_list: - rmsd = calcRMSD(subMol1,subMol2,nl1,nl2) - if(rmsd < minRMSD): - minRMSD = rmsd - n1 = nl1 - n2 = nl2 + for nl2 in n2_list: + rmsd = calcRMSD(subMol1,subMol2,nl1,nl2) + if(rmsd < minRMSD): + minRMSD = rmsd + n1 = nl1 + n2 = nl2 # match indices n1,n2 to the original molecule ind1,ind2 n1_orig = matchIDbyRMSD(subMol1,n1,mol1) n2_orig = matchIDbyRMSD(subMol2,n2,mol2) @@ -1098,23 +1098,23 @@ def disconnectedRecursive(mol1,mol2,ind1,ind2): matchDict1 = {} matchDict2 = {} for id1,id2 in zip(ind1,ind2): - # find id1 - key1 = '' - for i in range(0,len(n1_fragments)): - if id1 in n1_fragments[i]: - key1 = str(i) - break - # find id2 - key2 = '' - for i in range(0,len(n2_fragments)): - if id2 in n2_fragments[i]: - key2 = str(i) - break - key = key1+'_'+key2 - if key in matchDict1.keys(): + # find id1 + key1 = '' + for i in range(0,len(n1_fragments)): + if id1 in n1_fragments[i]: + key1 = str(i) + break + # find id2 + key2 = '' + for i in range(0,len(n2_fragments)): + if id2 in n2_fragments[i]: + key2 = str(i) + break + key = key1+'_'+key2 + if key in list(matchDict1.keys()): matchDict1[key].append(id1) matchDict2[key].append(id2) - else: + else: matchDict1[key] = [id1] matchDict2[key] = [id2] ################################## @@ -1123,19 +1123,19 @@ def disconnectedRecursive(mol1,mol2,ind1,ind2): minMatchRMSD = 99999.999 maxMatchKey = '' for key in matchDict1: - if len(matchDict1[key]) > maxMatchSize: - maxMatchSize = len(matchDict1[key]) - maxMatchKey = key - minMatchRMSD = Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(matchDict2[key],matchDict1[key])) - elif len(matchDict1[key]) == maxMatchSize: - rmsd = Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(matchDict2[key],matchDict1[key])) - if rmsd < minMatchRMSD: - minMatchRMSD = rmsd - maxMatchKey = key + if len(matchDict1[key]) > maxMatchSize: + maxMatchSize = len(matchDict1[key]) + maxMatchKey = key + minMatchRMSD = Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=list(zip(matchDict2[key],matchDict1[key]))) + elif len(matchDict1[key]) == maxMatchSize: + rmsd = Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=list(zip(matchDict2[key],matchDict1[key]))) + if rmsd < minMatchRMSD: + minMatchRMSD = rmsd + maxMatchKey = key ######################### ######## output ######### if maxMatchKey == '': - return([],[]) + return([],[]) return(matchDict1[maxMatchKey],matchDict2[maxMatchKey]) def sortInd(mol1,mol2,ind1,ind2): @@ -1144,16 +1144,16 @@ def sortInd(mol1,mol2,ind1,ind2): c1 = mol1.GetConformer() c2 = mol2.GetConformer() for id1 in ind1: - pos1 = c1.GetAtomPosition(id1) - minDist = 9999.999 - keep = -1 - for id2 in ind2: - pos2 = c2.GetAtomPosition(id2) + pos1 = c1.GetAtomPosition(id1) + minDist = 9999.999 + keep = -1 + for id2 in ind2: + pos2 = c2.GetAtomPosition(id2) if(pos1.Distance(pos2) res): - res = len(l) + if(len(l) > res): + res = len(l) return(res) def genFilename(filename,counter): if(counter == 0): - name = filename + name = filename else: - name = os.path.splitext(filename)[0]+"_"+str(counter)+os.path.splitext(filename)[1] + name = os.path.splitext(filename)[0]+"_"+str(counter)+os.path.splitext(filename)[1] return(name) def incrementByOne(foo): bar = [] for l in foo: - l = l+1 - bar.append(l) + l = l+1 + bar.append(l) return(bar) def mcsHremove(mol1,mol2,n1_list,n2_list,bH2H,bH2Hpolar,bH2heavy): n1 = [] n2 = [] for nfoo in n1_list: - for nbar in n2_list: + for nbar in n2_list: foo,bar = removeH(mol1,mol2,nfoo,nbar,bH2H,bH2Hpolar,bH2heavy) - n1.append(foo) - n2.append(bar) + n1.append(foo) + n2.append(bar) return(n1,n2) def mcsDist(mol1,mol2,n1_list,n2_list,d,bH2H,bH2heavy): @@ -1228,46 +1228,46 @@ def mcsDist(mol1,mol2,n1_list,n2_list,d,bH2H,bH2heavy): # distances maxMCS = 0 # size of the largest MCS fulfilling the distances for nfoo,nbar in zip(n1_list,n2_list): - alignID = zip(nfoo,nbar) + alignID = list(zip(nfoo,nbar)) ########################################## ###### o3a alignment may work better ##### - rmsd = Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(nbar,nfoo)) -# rmsd = alignOnSubset(mol1,mol2,alignID) # but it has some dependence on the molecule sequence, not sure if I trust it + rmsd = Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=list(zip(nbar,nfoo))) +# rmsd = alignOnSubset(mol1,mol2,alignID) # but it has some dependence on the molecule sequence, not sure if I trust it # print "RMSD after alignment: %f Angstroms" %rmsd x,y = distance_based(mol1,mol2,d,nfoo,nbar) - n1.append(x) - n2.append(y) - if(len(x)>maxMCS): - maxMCS = len(x) - + n1.append(x) + n2.append(y) + if(len(x)>maxMCS): + maxMCS = len(x) + nn1 = [] nn2 = [] # match rings and remove disconnected maxMCS = 0 for nfoo,nbar in zip(n1,n2): - # rings + # rings x,y = matchRings(mol1,mol2,nfoo,nbar) - # disconnected - #x,y = disconnectedMCS(mol1,mol2,x,y,bH2H,bH2heavy) - x,y = disconnectedRecursive(mol1,mol2,x,y) - nn1.append(x) - nn2.append(y) + # disconnected + #x,y = disconnectedMCS(mol1,mol2,x,y,bH2H,bH2heavy) + x,y = disconnectedRecursive(mol1,mol2,x,y) + nn1.append(x) + nn2.append(y) if(len(x)>maxMCS): maxMCS = len(x) - - print "maxMCS after distance treatment: %d" % maxMCS + + print("maxMCS after distance treatment: %d" % maxMCS) n1 = [] n2 = [] # only keep the largest MCSs maxSize = getLargestList(nn1+nn2) for nfoo,nbar in zip(nn1,nn2): - if(len(nfoo)==maxSize and len(nbar)==maxSize): - n1.append(nfoo) - n2.append(nbar) -# print "foo",nfoo,nbar + if(len(nfoo)==maxSize and len(nbar)==maxSize): + n1.append(nfoo) + n2.append(nbar) +# print "foo",nfoo,nbar return(n1,n2) - + def selectOneMCS(n1_list,n2_list,mol1,mol2): n1 = n1_list[0] n2 = n2_list[0] @@ -1287,18 +1287,18 @@ def selectOneMCS(n1_list,n2_list,mol1,mol2): # of the largest ones select the minRMSD rmsdMin = 9999.999 for nfoo,nbar in zip(n1_largest,n2_largest): - # align - alignID = zip(nbar,nfoo) - try: + # align + alignID = list(zip(nbar,nfoo)) + try: rmsd = Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=alignID) - except: - rmsd = rmsdMin*10.0 + except: + rmsd = rmsdMin*10.0 # x,y = distance_based(mol1,mol2,d,nfoo,nbar,True) - # compare + # compare if( rmsd < rmsdMin ): - rmsdMin = rmsd - n1 = nfoo - n2 = nbar + rmsdMin = rmsd + n1 = nfoo + n2 = nbar return(n1,n2) def checkSingleAtomInRingMap( rem1,n1,n2,mol1,mol2,r1,r2,dontRem1,dontRem2 ): @@ -1311,7 +1311,7 @@ def checkSingleAtomInRingMap( rem1,n1,n2,mol1,mol2,r1,r2,dontRem1,dontRem2 ): ring2 = a2.IsInRing() identifiedRings = [] if ring1==False and ring2==True: - for ar2 in r2:#.AtomRings(): # go over the rings + for ar2 in r2:#.AtomRings(): # go over the rings for at2 in ar2: # go over atoms # print "vg ",i,ar2,at2,j if at2==j: # found a ring of interest @@ -1326,7 +1326,7 @@ def checkSingleAtomInRingMap( rem1,n1,n2,mol1,mol2,r1,r2,dontRem1,dontRem2 ): for ring2 in identifiedRings: # print "vg ",r2 bFoo,mappedInd = countMapped( ring2,n2 ) -# print "vg ",bFoo,mappedInd,len(mappedInd) +# print "vg ",bFoo,mappedInd,len(mappedInd) if len(mappedInd)>1: # print "HERE" bRem = True @@ -1335,7 +1335,7 @@ def checkSingleAtomInRingMap( rem1,n1,n2,mol1,mol2,r1,r2,dontRem1,dontRem2 ): if bRem==False: # do not need to remove these atoms dontRem1.append(i) dontRem2.append(j) - + def matchFullRings(mol1,mol2,n1,n2): r1 = mol1.GetRingInfo() @@ -1353,31 +1353,31 @@ def matchFullRings(mol1,mol2,n1,n2): a2 = mol2.GetAtomWithIdx(j) ring1 = a1.IsInRing() ring2 = a2.IsInRing() - if( (ring1==True) and (ring2==False) ): - rem1.append(i) - rem2.append(j) + if( (ring1==True) and (ring2==False) ): + rem1.append(i) + rem2.append(j) elif( (ring1==False) and (ring2==True) ): - rem1.append(i) - rem2.append(j) + rem1.append(i) + rem2.append(j) elif( (ring1==True) and (ring2==True) ): - mapped1 = False - mapped2 = False + mapped1 = False + mapped2 = False # here only checking if, given one morphable atom in a ring, # is there at least one ring which would harbor this atom # and all the other atoms in that ring would also be morphable - for ar1 in r1:#.AtomRings(): - if( i in ar1 ): - mapped1 = isMapped(ar1,n1) - if( mapped1 == True): - break + for ar1 in r1:#.AtomRings(): + if( i in ar1 ): + mapped1 = isMapped(ar1,n1) + if( mapped1 == True): + break for ar2 in r2:#.AtomRings(): - if( j in ar2 ): + if( j in ar2 ): mapped2 = isMapped(ar2,n2) if( mapped2 == True): break - if( (mapped1==False) or (mapped2==False) ): - rem1.append(i) - rem2.append(j) + if( (mapped1==False) or (mapped2==False) ): + rem1.append(i) + rem2.append(j) # before removing, check for a special case: # a single non-ring atom could be allowed to map to a single ring atom @@ -1445,10 +1445,10 @@ def matchFullRings(mol1,mol2,n1,n2): n1_out,n2_out = removeInd( n1,n2,minRem,minRemB ) # print n1,minRem break - if minRemSize>0 and minRemSize<999: + if minRemSize>0 and minRemSize<999: continue # sys.exit(0) - + # go over the rings in the second molecule for ar2 in r2:#.AtomRings(): bRem2,mappedInd = countMapped(ar2,n2) @@ -1479,10 +1479,10 @@ def matchFullRings(mol1,mol2,n1,n2): # remove the atoms n1_out,n2_out = removeInd( n1,n2,minRemB,minRem ) break - if minRemSize>0 and minRemSize<999: + if minRemSize>0 and minRemSize<999: continue - bFound = False + bFound = False return(n1_out,n2_out) @@ -1514,9 +1514,9 @@ def countMapped(ring,ind): def isMapped(ring,ind): for a in ring: if( a in ind): - continue - else: - return(False) + continue + else: + return(False) return(True) def mcs(mol1, mol2, molForMcs1,molForMcs2, bH2H, bH2Hpolar, bH2heavy, bdMCS, bRingsOnly, d, bChiral, sigmaHoleID1, sigmaHoleID2, t=None): @@ -1527,10 +1527,10 @@ def mcs(mol1, mol2, molForMcs1,molForMcs2, bH2H, bH2Hpolar, bH2heavy, bdMCS, bRi carbonize(foo,bH2heavy,42) carbonize(bar,bH2heavy,43) else: - carbonize(foo,bH2heavy) - carbonize(bar,bH2heavy) + carbonize(foo,bH2heavy) + carbonize(bar,bH2heavy) mols = [foo,bar] - print "Searching..." + print("Searching...") res = MCS.FindMCS(mols,ringMatchesRingOnly=True, completeRingsOnly=True, atomCompare='elements', bondCompare='any', timeout=int(t), maximize='bonds') # for new RDKit-2018 use below # res = rdFMCS.FindMCS(mols,ringMatchesRingOnly=True, completeRingsOnly=True, timeout=int(t), maximizeBonds=True, bondCompare=rdFMCS.BondCompare.CompareAny, atomCompare=rdFMCS.AtomCompare.CompareElements) @@ -1544,7 +1544,7 @@ def mcs(mol1, mol2, molForMcs1,molForMcs2, bH2H, bH2Hpolar, bH2heavy, bdMCS, bRi return(n1_list,n2_list) n1_list = pp.GetMatches(foo) n2_list = pp.GetMatches(bar) - print 'Found %d MCSs in total (mol1: %d, mol2: %d), each with %d atoms and %d bonds' % (len(n1_list)*len(n2_list),len(n1_list),len(n2_list),res.numAtoms,res.numBonds) + print('Found %d MCSs in total (mol1: %d, mol2: %d), each with %d atoms and %d bonds' % (len(n1_list)*len(n2_list),len(n1_list),len(n2_list),res.numAtoms,res.numBonds)) # if hydrogens to be removed n1_list,n2_list = mcsHremove(mol1,mol2,n1_list,n2_list,bH2H,bH2Hpolar,bH2heavy) # from this point n1_list and n2_list elements must match 1to1, i.e. the number of elements in the lists is the same @@ -1557,11 +1557,11 @@ def mcs(mol1, mol2, molForMcs1,molForMcs2, bH2H, bH2Hpolar, bH2heavy, bdMCS, bRi for n1,n2 in zip(n1_list,n2_list): # n1,n2 = removePolarHmappings(mol1,mol2,n1,n2,bH2Hpolar) # n1,n2 = tripleBond(mol1,mol2,n1,n2) - n1,n2 = checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy) + n1,n2 = checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy) #n1,n2 = disconnectedMCS(mol1,mol2,n1,n2,bH2H,bH2heavy) - n1,n2 = disconnectedRecursive(mol1,mol2,n1,n2) - n1_foo.append(n1) - n2_foo.append(n2) + n1,n2 = disconnectedRecursive(mol1,mol2,n1,n2) + n1_foo.append(n1) + n2_foo.append(n2) n1_list = cp.copy(n1_foo) n2_list = cp.copy(n2_foo) @@ -1569,21 +1569,21 @@ def mcs(mol1, mol2, molForMcs1,molForMcs2, bH2H, bH2Hpolar, bH2heavy, bdMCS, bRi # test # for n1,n2 in zip(n1_list,n2_list): # print "foo" -# for i1,i2 in zip(n1,n2): -# print i1+1,i2+1 -# print "\n"; +# for i1,i2 in zip(n1,n2): +# print i1+1,i2+1 +# print "\n"; # sys.exit(0) ############################################# ######### chirality check ################### # bChiral = True#False#True if( bChiral==True ): - print "Chirality check." + print("Chirality check.") n1_foo = [] n2_foo = [] for n1,n2 in zip(n1_list,n2_list): - while(bCheckChiralViolation(mol1,mol2,n1,n2)==True): + while(bCheckChiralViolation(mol1,mol2,n1,n2)==True): n1,n2 = checkChiral(mol1,mol2,n1,n2) - n1,n2 = disconnectedRecursive(mol1,mol2,n1,n2) + n1,n2 = disconnectedRecursive(mol1,mol2,n1,n2) n1_foo.append(n1) n2_foo.append(n2) n1_list = cp.copy(n1_foo) @@ -1605,7 +1605,7 @@ def mcs(mol1, mol2, molForMcs1,molForMcs2, bH2H, bH2Hpolar, bH2heavy, bdMCS, bRi ######### do not break rings ################ bBreakRings = False if( bBreakRings==False ): - print "Avoiding breaking rings." + print("Avoiding breaking rings.") n1_foo = [] n2_foo = [] for n1,n2 in zip(n1_list,n2_list): @@ -1618,26 +1618,26 @@ def mcs(mol1, mol2, molForMcs1,molForMcs2, bH2H, bH2Hpolar, bH2heavy, bdMCS, bRi # test # for n1,n2 in zip(n1_list,n2_list): # print "foo" -# for i1,i2 in zip(n1,n2): -# print i1+1,i2+1 -# print "\n"; +# for i1,i2 in zip(n1,n2): +# print i1+1,i2+1 +# print "\n"; # sys.exit(0) # if distances to be compared if(bdMCS==True): - n1_list,n2_list = mcsDist(mol1,mol2,n1_list,n2_list,d,bH2H,bH2heavy) - # due to meeting distance criterium - # the rings may be broken - # and disconnected fragments may appear - bBreakRings = False - if( bBreakRings==False ): - print "Avoiding breaking rings after meeting distance criterium.\n" + n1_list,n2_list = mcsDist(mol1,mol2,n1_list,n2_list,d,bH2H,bH2heavy) + # due to meeting distance criterium + # the rings may be broken + # and disconnected fragments may appear + bBreakRings = False + if( bBreakRings==False ): + print("Avoiding breaking rings after meeting distance criterium.\n") n1_foo = [] n2_foo = [] for n1,n2 in zip(n1_list,n2_list): n1,n2 = matchFullRings(mol1,mol2,n1,n2) - n1,n2 = disconnectedRecursive(mol1,mol2,n1,n2) + n1,n2 = disconnectedRecursive(mol1,mol2,n1,n2) n1_foo.append(n1) n2_foo.append(n2) n1_list = cp.copy(n1_foo) @@ -1647,29 +1647,29 @@ def mcs(mol1, mol2, molForMcs1,molForMcs2, bH2H, bH2Hpolar, bH2heavy, bdMCS, bRi n1,n2 = selectOneMCS(n1_list,n2_list,mol1,mol2) # one more final check for possible issues with the 1-2, 1-3 and 1-4 interactions - n1,n2 = checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy) + n1,n2 = checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy) # remove sigma hole virtual particles n1,n2 = remove_sigmaHoles( n1,n2,sigmaHoleID1,sigmaHoleID2) - print 'Final MCS that survived after pruning: %d atoms' % (len(n1)) + print('Final MCS that survived after pruning: %d atoms' % (len(n1))) return n1,n2 def checkRingsOnlyFlag(mol1,mol2): flag = 0 for atom in mol1.GetAtoms(): - if(atom.IsInRing()==True): - flag = flag + 1 - break + if(atom.IsInRing()==True): + flag = flag + 1 + break for atom in mol2.GetAtoms(): if(atom.IsInRing()==True): flag = flag + 1 break if(flag==2): - return(True) + return(True) else: - return(False) + return(False) def main(argv): @@ -1700,10 +1700,10 @@ def main(argv): Option( "-H2heavy", "bool", "False", "should hydrogen be morphed into a heavy atom (also sets -H2H to true)"), Option( "-RingsOnly", "bool", "False", "should rings only be used in the MCS search or alignment"), Option( "-dMCS", "bool", "False", "find MCS, superimpose the structures based on the MCS, apply distance in\ - Cartesian coordinate space to define the morphes"), + Cartesian coordinate space to define the morphes"), Option( "-chirality", "bool", "True", "perform chirality check for MCS mapping"), Option( "-d", "float", "0.05", "distance (nm) between atoms to consider them morphable"), - Option( "-timeout", "float", "None", "maximum time (s) for an MCS search"), + Option( "-timeout", "float", "None", "maximum time (s) for an MCS search"), ] help_text = () @@ -1711,7 +1711,7 @@ def main(argv): # pass options, files and the command line to pymacs cmdl = Commandline( argv, options = options, fileoptions = files, program_desc = help_text, check_for_existing_files = False, version = "0.0" ) - + # deal with the flags bH2H = False bH2Hpolar = False @@ -1719,17 +1719,17 @@ def main(argv): d = 0.05 timeout = None if(cmdl['-H2H']==True): - bH2H = True + bH2H = True if(cmdl['-H2Hpolar']==True): bH2Hpolar = True bH2heavy = False if(cmdl['-H2heavy']==True): bH2heavy = True - bH2H = True + bH2H = True if(cmdl.opt['-d'].is_set): - d = cmdl['-d'] + d = cmdl['-d'] if(cmdl.opt['-timeout'].is_set): - timeout = cmdl['-timeout'] + timeout = cmdl['-timeout'] if(cmdl['-chirality']==False): bChiral = False @@ -1738,26 +1738,26 @@ def main(argv): bAlignment = True bMCS = True if cmdl.opt['-alignment'].is_set: - bAlignment = cmdl['-alignment'] - if cmdl['-alignment']==True: - if cmdl.opt['-mcs'].is_set and cmdl['-mcs']==False: - bMCS = False - if cmdl.opt['-mcs'].is_set==False: - bMCS = False - if cmdl.opt['-mcs'].is_set: - bMCS = cmdl['-mcs'] + bAlignment = cmdl['-alignment'] + if cmdl['-alignment']==True: + if cmdl.opt['-mcs'].is_set and cmdl['-mcs']==False: + bMCS = False + if cmdl.opt['-mcs'].is_set==False: + bMCS = False + if cmdl.opt['-mcs'].is_set: + bMCS = cmdl['-mcs'] if cmdl['-mcs']==True: if cmdl.opt['-alignment'].is_set and cmdl['-alignment']==False: bAlignment = False if cmdl.opt['-alignment'].is_set==False: bAlignment = False if bMCS==False and bAlignment==False: - print "No method (alignment, mcs) was selected." - sys.exit(0) - print "Morphable atoms will be identified using the following methods:" - print "Alignment: ",bAlignment - print "MCS: ",bMCS - print "\n" + print("No method (alignment, mcs) was selected.") + sys.exit(0) + print("Morphable atoms will be identified using the following methods:") + print("Alignment: ",bAlignment) + print("MCS: ",bMCS) + print("\n") ###################################### # read index @@ -1790,14 +1790,14 @@ def main(argv): molForMcs1 = cp.deepcopy(mol1) molForMcs2 = cp.deepcopy(mol2) try: - rdmolops.AssignAtomChiralTagsFromStructure(mol1) - rdmolops.AssignAtomChiralTagsFromStructure(mol2) + rdmolops.AssignAtomChiralTagsFromStructure(mol1) + rdmolops.AssignAtomChiralTagsFromStructure(mol2) molForMcs1 = cp.deepcopy(mol1) molForMcs2 = cp.deepcopy(mol2) - rdmolops.AssignStereochemistry(mol1) - rdmolops.AssignStereochemistry(mol2) + rdmolops.AssignStereochemistry(mol1) + rdmolops.AssignStereochemistry(mol2) except: - print "Chirality not assigned" + print("Chirality not assigned") # mol1 = Chem.SDMolSupplier(cmdl['-i1'],removeHs=False,sanitize=True) # mol2 = Chem.SDMolSupplier(cmdl['-i2'],removeHs=False,sanitize=True) @@ -1810,11 +1810,11 @@ def main(argv): bRingsOnly = False bYesRings = checkRingsOnlyFlag(mol1,mol2) if(cmdl['-RingsOnly']==True): - if( bYesRings==True ): - bRingsOnly=True - else: - print "-RingsOnly flag is unset, because one (or both) molecule has no rings\n" - + if( bYesRings==True ): + bRingsOnly=True + else: + print("-RingsOnly flag is unset, because one (or both) molecule has no rings\n") + n1 = [] n2 = [] @@ -1833,82 +1833,82 @@ def main(argv): n1mcs = [] n2mcs = [] if(bMCS==True): - print "The topology matching approach will be used (MCS)" - print "fmcs module: Copyright (c) 2012 Andrew Dalke Scientific AB\n" - if(bRingsOnly==True): - n1mcs,n2mcs = mcs(mol1,mol2,molForMcs1,molForMcs2,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],bRingsOnly,d,bChiral,sigmaHoleID1,sigmaHoleID2,timeout) - else: - print "Trying to run an MCS using all atoms..." + print("The topology matching approach will be used (MCS)") + print("fmcs module: Copyright (c) 2012 Andrew Dalke Scientific AB\n") + if(bRingsOnly==True): + n1mcs,n2mcs = mcs(mol1,mol2,molForMcs1,molForMcs2,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],bRingsOnly,d,bChiral,sigmaHoleID1,sigmaHoleID2,timeout) + else: + print("Trying to run an MCS using all atoms...") n1A,n2A = mcs(mol1,mol2,molForMcs1,molForMcs2,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],False,d,bChiral,sigmaHoleID1,sigmaHoleID2,timeout) n1mcs = n1A n2mcs = n2A - print "Size of mapping: ",len(n1mcs) + print("Size of mapping: ",len(n1mcs)) if( bYesRings==True ): - print "Trying to run an MCS using rings only..." + print("Trying to run an MCS using rings only...") n1B,n2B = mcs(mol1,mol2,molForMcs1,molForMcs2,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],True,d,bChiral,sigmaHoleID1,sigmaHoleID2,timeout) if(len(n1A)<=len(n1B)): - print "Using ring only MCS result." + print("Using ring only MCS result.") n1mcs = n1B n2mcs = n2B else: - print "Using all atom MCS result." + print("Using all atom MCS result.") if len(n1mcs)==0: - bMCSfailed = True + bMCSfailed = True ######################################## ####### alignment ###################### n1align = [] n2align = [] if( (bAlignment==True) or (bMCSfailed==True) ): - if bMCSfailed==True: - print "The MCS approach did not find any mapping" - print "\nThe alignment approach will be used" - print "Tosco, P., Balle, T. & Shiri, F. Open3DALIGN: an open-source software aimed at unsupervised ligand alignment. J Comput Aided Mol Des 25:777-83 (2011)" - print "Alignment is based on atom logP contributions: S. A. Wildman and G. M. Crippen JCICS _39_ 868-873 (1999)\n" - # only use rings - if(bRingsOnly==True): + if bMCSfailed==True: + print("The MCS approach did not find any mapping") + print("\nThe alignment approach will be used") + print("Tosco, P., Balle, T. & Shiri, F. Open3DALIGN: an open-source software aimed at unsupervised ligand alignment. J Comput Aided Mol Des 25:777-83 (2011)") + print("Alignment is based on atom logP contributions: S. A. Wildman and G. M. Crippen JCICS _39_ 868-873 (1999)\n") + # only use rings + if(bRingsOnly==True): n1align,n2align,pyO3A = o3a_alignment(mol1,mol2,bH2H,bH2Hpolar,bH2heavy,bRingsOnly,sigmaHoleID1,sigmaHoleID2,True,d) - # else try both options and choose better - else: - print "Trying to align all atoms..." + # else try both options and choose better + else: + print("Trying to align all atoms...") n1align,n2align,pyO3A = o3a_alignment(mol1,mol2,bH2H,bH2Hpolar,bH2heavy,False,sigmaHoleID1,sigmaHoleID2,True,d) - print "Size of mapping: ",len(n1align) - if( bYesRings==True ): - print "Trying to align rings only..." + print("Size of mapping: ",len(n1align)) + if( bYesRings==True ): + print("Trying to align rings only...") mol1 = cp.deepcopy(molcp1) mol2 = cp.deepcopy(molcp2) n1B,n2B,pyO3A = o3a_alignment(mol1,mol2,bH2H,bH2Hpolar,bH2heavy,True,sigmaHoleID1,sigmaHoleID2,True,d) - print "Size of mapping: ",len(n1B) - if(len(n1align)<=len(n1B)): - print "Using ring only alignment result." - n1align = n1B - n2align = n2B - else: - print "Using all atom alignment result." + print("Size of mapping: ",len(n1B)) + if(len(n1align)<=len(n1B)): + print("Using ring only alignment result.") + n1align = n1B + n2align = n2B + else: + print("Using all atom alignment result.") # select the better result: mcs or align if len(n1align)>=len(n1mcs): - print "The final result is based on the O3A alignment." - n1 = n1align - n2 = n2align + print("The final result is based on the O3A alignment.") + n1 = n1align + n2 = n2align else: - print "The final result is based on the MCS." - n1 = n1mcs - n2 = n2mcs + print("The final result is based on the MCS.") + n1 = n1mcs + n2 = n2mcs #-------------------------------------------------------------------------------# #-------------------------------------------------------------------------------# # also try the same procedure by inverting the ordering of mol1 and mol2 # ########################################### ########### mcs ########################### - print "\n********************************************************************************************************************************" - print "To ensure that the mapping is symmetric, i.e. mol1->mol2=mol2->mol1, we repeat the same procedure by swapping the molecule order.\n" - print "********************************************************************************************************************************" + print("\n********************************************************************************************************************************") + print("To ensure that the mapping is symmetric, i.e. mol1->mol2=mol2->mol1, we repeat the same procedure by swapping the molecule order.\n") + print("********************************************************************************************************************************") bMCSfailed = False n1mcs = [] n2mcs = [] if(bMCS==True): - print "Running MCS:" - if(bRingsOnly==True): - n2mcs,n1mcs = mcs(mol2,mol1,molForMcs2,molForMcs1,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],bRingsOnly,d,bChiral,sigmaHoleID2,sigmaHoleID1,timeout) - else: + print("Running MCS:") + if(bRingsOnly==True): + n2mcs,n1mcs = mcs(mol2,mol1,molForMcs2,molForMcs1,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],bRingsOnly,d,bChiral,sigmaHoleID2,sigmaHoleID1,timeout) + else: n2A,n1A = mcs(mol2,mol1,molForMcs2,molForMcs1,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],False,d,bChiral,sigmaHoleID2,sigmaHoleID1,timeout) n1mcs = n1A n2mcs = n2A @@ -1917,65 +1917,65 @@ def main(argv): if(len(n1A)<=len(n1B)): n1mcs = n1B n2mcs = n2B - if len(n1mcs)==0: - bMCSfailed = True + if len(n1mcs)==0: + bMCSfailed = True ######################################## ####### alignment ###################### n1align = [] n2align = [] if( (bAlignment==True) or (bMCSfailed==True) ): - print "\nRunning alignment:" - if(bRingsOnly==True): + print("\nRunning alignment:") + if(bRingsOnly==True): n2align,n1align,pyO3A = o3a_alignment(mol2,mol1,bH2H,bH2Hpolar,bH2heavy,bRingsOnly,sigmaHoleID2,sigmaHoleID1,True,d) - else: + else: n2align,n1align,pyO3A = o3a_alignment(mol2,mol1,bH2H,bH2Hpolar,bH2heavy,False,sigmaHoleID2,sigmaHoleID1,True,d) - print "Size of mapping: ",len(n1align) - if( bYesRings==True ): + print("Size of mapping: ",len(n1align)) + if( bYesRings==True ): mol1 = cp.deepcopy(molcp1) mol2 = cp.deepcopy(molcp2) n2B,n1B,pyO3A = o3a_alignment(mol2,mol1,bH2H,bH2Hpolar,bH2heavy,True,sigmaHoleID2,sigmaHoleID1,True,d) - print "Size of mapping: ",len(n1B) - if(len(n1align)<=len(n1B)): - n1align = n1B - n2align = n2B + print("Size of mapping: ",len(n1B)) + if(len(n1align)<=len(n1B)): + n1align = n1B + n2align = n2B # select the better result (mcs or align) and compare with the non-inverted mapping if (len(n1align)<=len(n1)) and (len(n1mcs)<=len(n1)): - print "Swapping of the molecules did not yield a better atom mapping." + print("Swapping of the molecules did not yield a better atom mapping.") if (len(n1align)>=len(n1mcs)) and (len(n1align)>len(n1)): - print "The final result is based on the O3A alignment after swapping the molecule order (mol2-mol1)." - n1 = n1align - n2 = n2align + print("The final result is based on the O3A alignment after swapping the molecule order (mol2-mol1).") + n1 = n1align + n2 = n2align elif (len(n1align)len(n1)): - print "The final result is based on the MCS after swapping the molecule order (mol2-mol1)." - n1 = n1mcs - n2 = n2mcs - print "\n" + print("The final result is based on the MCS after swapping the molecule order (mol2-mol1).") + n1 = n1mcs + n2 = n2mcs + print("\n") #*******************************************************************************# #*******************************************************************************# #*******************************************************************************# # a check if( len(n1) != len(n2) ): - print "Warning: something went wrong." - print "Number of the morphable atoms in the ligands does not match.\n" - + print("Warning: something went wrong.") + print("Number of the morphable atoms in the ligands does not match.\n") + # calculate score score = calcScore(mol1,mol2,n1,n2,bH2H,bH2heavy) # print some output - print "FINAL RESULTS" + print("FINAL RESULTS") if( bH2H==True or bH2heavy==True ): - print "Atoms considered in mol1: ",mol1.GetNumAtoms() - print "Atoms considered in mol2: ",mol2.GetNumAtoms() + print("Atoms considered in mol1: ",mol1.GetNumAtoms()) + print("Atoms considered in mol2: ",mol2.GetNumAtoms()) else: - print "Atoms considered in mol1: ",mol1.GetNumHeavyAtoms() - print "Atoms considered in mol2: ",mol2.GetNumHeavyAtoms() - print "Morphable atoms in both molecules: ",len(n1),len(n2) - print "Dissimilarity (distance) score: %.4f\n" % score + print("Atoms considered in mol1: ",mol1.GetNumHeavyAtoms()) + print("Atoms considered in mol2: ",mol2.GetNumHeavyAtoms()) + print("Morphable atoms in both molecules: ",len(n1),len(n2)) + print("Dissimilarity (distance) score: %.4f\n" % score) if(cmdl['-score']): - fp = open(cmdl['-score'],'w') - fp.write("Score: %.4f\n" % score) - fp.close() + fp = open(cmdl['-score'],'w') + fp.write("Score: %.4f\n" % score) + fp.close() restoreAtomNames(mol1,atomNameID1) restoreAtomNames(mol2,atomNameID2) @@ -1985,15 +1985,15 @@ def main(argv): # Chem.rdMolAlign.AlignMol(mol1,molcp1,atomMap=zip(n1,n1)) Chem.MolToPDBFile(molcp1,cmdl['-opdb1']) if cmdl.opt['-opdb2'].is_set: -# if( cmdl['-mcs']==True ): +# if( cmdl['-mcs']==True ): try: # Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(n2,n1)) - Chem.rdMolAlign.AlignMol(mol2,molcp1,atomMap=zip(n2,n1)) + Chem.rdMolAlign.AlignMol(mol2,molcp1,atomMap=list(zip(n2,n1))) except: - print "Cannot superimpose -opdb2 structure. Maybe no morphable atoms have been found\n" + print("Cannot superimpose -opdb2 structure. Maybe no morphable atoms have been found\n") Chem.MolToPDBFile(mol2,cmdl['-opdb2']) if cmdl.opt['-opdbm1'].is_set: - mol = subMolByIndex(molcp1,n1) + mol = subMolByIndex(molcp1,n1) Chem.MolToPDBFile(mol,cmdl['-opdbm1']) if cmdl.opt['-opdbm2'].is_set: mol = subMolByIndex(mol2,n2) @@ -2004,5 +2004,3 @@ def main(argv): write_pairs(n1,n2,pairsFile) main( sys.argv ) - - diff --git a/pmx/scripts/ligands/atoms_to_morph_rdkit2018.py b/pmx/scripts/ligands/atoms_to_morph_rdkit2018.py index a465a627..8db89ab7 100755 --- a/pmx/scripts/ligands/atoms_to_morph_rdkit2018.py +++ b/pmx/scripts/ligands/atoms_to_morph_rdkit2018.py @@ -50,12 +50,12 @@ def alignOnSubset(mol1,mol2,constrMap): # only heavy atoms can be constraints rem = [] for c in constrMap: - a1 = mol1.GetAtomWithIdx(c[0]) - a2 = mol2.GetAtomWithIdx(c[1]) + a1 = mol1.GetAtomWithIdx(c[0]) + a2 = mol2.GetAtomWithIdx(c[1]) id1 = a1.GetAtomicNum() id2 = a2.GetAtomicNum() if((id1==1) or (id2==1)): - rem.append(c) + rem.append(c) # remove for i in rem: constrMap.remove(i) @@ -71,43 +71,43 @@ def getAttr(n1,n2,iStart,iEnd): jStart = None jEnd = None for foo,bar in zip(n1,n2): - if(foo==iStart): - jStart = bar - if(foo==iEnd): - jEnd = bar + if(foo==iStart): + jStart = bar + if(foo==iEnd): + jEnd = bar return(jStart,jEnd) def getMapped(n1,n2,ind1): ind2 = None for id1,id2 in zip(n1,n2): - if id1==ind1: - ind2=id2 - return(ind2) + if id1==ind1: + ind2=id2 + return(ind2) return(ind2) def getMappedList(n1,n2,indList1): indList2 = [] for ind1 in indList1: for id1,id2 in zip(n1,n2): - if id1==ind1: - indList2.append(id2) - break + if id1==ind1: + indList2.append(id2) + break return(indList2) def checkNeighDist(mol1,mol2,nb1,n1,n2,rem1,rem2): c1 = mol1.GetConformer() c2 = mol2.GetConformer() for neigh1 in nb1: - ind1 = neigh1.GetIdx() - if ind1 in n1: - ind2 = getMapped(n1,n2,ind1) - if ind2!=None: - dist = distance_based(mol1,mol2,0.0,id1=[ind1],id2=[ind2],calcOnly=True) -# print ind1,ind2,dist - if dist > 0.15: # 0.15 nm distance should be forgiving enough, but also catch the cases of chirality inversions - if (ind1 not in rem1) and (ind2 not in rem2): - rem1.append(ind1) - rem2.append(ind2) + ind1 = neigh1.GetIdx() + if ind1 in n1: + ind2 = getMapped(n1,n2,ind1) + if ind2!=None: + dist = distance_based(mol1,mol2,0.0,id1=[ind1],id2=[ind2],calcOnly=True) +# print ind1,ind2,dist + if dist > 0.15: # 0.15 nm distance should be forgiving enough, but also catch the cases of chirality inversions + if (ind1 not in rem1) and (ind2 not in rem2): + rem1.append(ind1) + rem2.append(ind2) def localEnvironment(mol,i,n): a1 = mol.GetAtomWithIdx(i) @@ -116,14 +116,14 @@ def localEnvironment(mol,i,n): list12 = [] list13 = [] for a2 in nb1: - ind1 = a2.GetIdx() - if ind1 in n: - list12.append(ind1) + ind1 = a2.GetIdx() + if ind1 in n: + list12.append(ind1) nb2 = a2.GetNeighbors() - for a3 in nb2: - ind2 = a3.GetIdx() - if (ind2 in n) and (ind2 not in list12) and (ind2 not in list13) and (ind2 != i): - list13.append(ind2) + for a3 in nb2: + ind2 = a3.GetIdx() + if (ind2 in n) and (ind2 not in list12) and (ind2 not in list13) and (ind2 != i): + list13.append(ind2) # final list listFinal = [i] + list12 + list13 return(listFinal) @@ -131,9 +131,9 @@ def localEnvironment(mol,i,n): def checkChiral(mol1,mol2,n1,n2): # create constraint for alignment - constrMap = zip(n1,n2) + constrMap = list(zip(n1,n2)) # align on the subset n1,n2 - Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(n2,n1)) + Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=list(zip(n2,n1))) bonds1 = mol1.GetBonds() bonds2 = mol2.GetBonds() # create two dictionaries for mappings [n1] = n2 @@ -153,29 +153,29 @@ def checkChiral(mol1,mol2,n1,n2): bNonsingleBond1 = check_nonsingle_bonds( mol1, mol2, bonds1, n1, n2, dictn1n2 ) bNonsingleBond2 = check_nonsingle_bonds( mol2, mol1, bonds2, n2, n1, dictn2n1 ) if (str(chirality1) != "CHI_UNSPECIFIED") or (bNonsingleBond1==True): -# print "1",i1,chirality1 - # try fitting locally on the 1-2, 1-3 atoms - localEnv1 = localEnvironment(mol1,i1,n1) - if len(localEnv1)>2: - localEnv2 = getMappedList(n1,n2,localEnv1) - Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(localEnv2,localEnv1)) -# alignOnSubset(mol1,mol2,zip(localEnv1,localEnv2)) - # get the neighbours - nb1 = a1.GetNeighbors() - # check if the matched neighbours in the aligned molecules are too far - checkNeighDist(mol1,mol2,nb1,n1,n2,rem1,rem2) +# print "1",i1,chirality1 + # try fitting locally on the 1-2, 1-3 atoms + localEnv1 = localEnvironment(mol1,i1,n1) + if len(localEnv1)>2: + localEnv2 = getMappedList(n1,n2,localEnv1) + Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=list(zip(localEnv2,localEnv1))) +# alignOnSubset(mol1,mol2,zip(localEnv1,localEnv2)) + # get the neighbours + nb1 = a1.GetNeighbors() + # check if the matched neighbours in the aligned molecules are too far + checkNeighDist(mol1,mol2,nb1,n1,n2,rem1,rem2) if (str(chirality2) != "CHI_UNSPECIFIED") or (bNonsingleBond2==True): -# print "2",i2,chirality2 +# print "2",i2,chirality2 # try fitting locally on the 1-2, 1-3 atoms localEnv2 = localEnvironment(mol2,i2,n2) if len(localEnv2)>2: localEnv1 = getMappedList(n2,n1,localEnv2) - Chem.rdMolAlign.AlignMol(mol1,mol2,atomMap=zip(localEnv1,localEnv2)) + Chem.rdMolAlign.AlignMol(mol1,mol2,atomMap=list(zip(localEnv1,localEnv2))) # alignOnSubset(mol1,mol2,zip(localEnv1,localEnv2)) # get the neighbours nb2 = a2.GetNeighbors() # check if the matched neighbours in the aligned molecules are too far - checkNeighDist(mol2,mol1,nb2,n2,n1,rem2,rem1) + checkNeighDist(mol2,mol1,nb2,n2,n1,rem2,rem1) ####### remove ####### n1_out = [] @@ -194,9 +194,9 @@ def bCheckChiralViolation(mol1,mol2,n1,n2): if len(n1)<2 and len(n2)<2: return(bViolation) # create constraint for alignment - constrMap = zip(n1,n2) + constrMap = list(zip(n1,n2)) # align on the subset n1,n2 - Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(n2,n1)) + Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=list(zip(n2,n1))) rem1 = [] rem2 = [] bonds1 = mol1.GetBonds() @@ -204,7 +204,7 @@ def bCheckChiralViolation(mol1,mol2,n1,n2): # create two dictionaries for mappings [n1] = n2 dictn1n2 = mappingDict( n1,n2 ) dictn2n1 = mappingDict( n2,n1 ) - + for i1,i2 in zip(n1,n2): a1 = mol1.GetAtomWithIdx(i1) a2 = mol2.GetAtomWithIdx(i2) @@ -219,26 +219,26 @@ def bCheckChiralViolation(mol1,mol2,n1,n2): # print bNonsingleBond1 # bonds_a1 = find_atom_bonds( i1, a1, bonds1 ) # find all bonds in which a1 takes part # sys.exit(0) - if (str(chirality1) != "CHI_UNSPECIFIED") or (bNonsingleBond1==True): -# print "1check",i1,chirality1 + if (str(chirality1) != "CHI_UNSPECIFIED") or (bNonsingleBond1==True): +# print "1check",i1,chirality1 localEnv1 = localEnvironment(mol1,i1,n1) if len(localEnv1)>2: localEnv2 = getMappedList(n1,n2,localEnv1) - Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(localEnv2,localEnv1)) + Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=list(zip(localEnv2,localEnv1))) #alignOnSubset(mol1,mol2,zip(localEnv1,localEnv2)) nb1 = a1.GetNeighbors() checkNeighDist(mol1,mol2,nb1,n1,n2,rem1,rem2) - if (str(chirality2) != "CHI_UNSPECIFIED") or (bNonsingleBond2==True): -# print "2check",i2,chirality2 + if (str(chirality2) != "CHI_UNSPECIFIED") or (bNonsingleBond2==True): +# print "2check",i2,chirality2 localEnv2 = localEnvironment(mol2,i2,n2) if len(localEnv2)>2: localEnv1 = getMappedList(n2,n1,localEnv2) - Chem.rdMolAlign.AlignMol(mol1,mol2,atomMap=zip(localEnv1,localEnv2)) + Chem.rdMolAlign.AlignMol(mol1,mol2,atomMap=list(zip(localEnv1,localEnv2))) #alignOnSubset(mol1,mol2,zip(localEnv1,localEnv2)) nb2 = a2.GetNeighbors() checkNeighDist(mol2,mol1,nb2,n2,n1,rem2,rem1) - if len(rem1)+len(rem2)>0: - return(True) + if len(rem1)+len(rem2)>0: + return(True) return(bViolation) # bond length table @@ -297,22 +297,22 @@ def checkTopRemove(mol1,mol2,n1,n2,startList,endList): rem1 = [] rem2 = [] for iStart,iEnd in zip(startList,endList): - jStart,jEnd = getAttr(n1,n2,iStart,iEnd) - # count iStart mapped neighbours - startNeighb = 0 - for b1 in mol1.GetBonds(): + jStart,jEnd = getAttr(n1,n2,iStart,iEnd) + # count iStart mapped neighbours + startNeighb = 0 + for b1 in mol1.GetBonds(): foo = b1.GetBeginAtomIdx() bar = b1.GetEndAtomIdx() - if( iStart==foo ): # atom of interest - a,b = getAttr(n1,n2,iStart,bar) - if( (a!=None) and (b!=None) ): - startNeighb = startNeighb+1 - elif( iStart==bar ): # atom of interest + if( iStart==foo ): # atom of interest + a,b = getAttr(n1,n2,iStart,bar) + if( (a!=None) and (b!=None) ): + startNeighb = startNeighb+1 + elif( iStart==bar ): # atom of interest a,b = getAttr(n1,n2,iStart,foo) if( (a!=None) and (b!=None) ): startNeighb = startNeighb+1 - # count iEnd mapped neighbour - endNeighb = 0 + # count iEnd mapped neighbour + endNeighb = 0 for b1 in mol1.GetBonds(): foo = b1.GetBeginAtomIdx() bar = b1.GetEndAtomIdx() @@ -320,122 +320,122 @@ def checkTopRemove(mol1,mol2,n1,n2,startList,endList): a,b = getAttr(n1,n2,iEnd,bar) if( (a!=None) and (b!=None) ): endNeighb = endNeighb+1 - elif( iEnd==bar ): # atom of interest + elif( iEnd==bar ): # atom of interest a,b = getAttr(n1,n2,iEnd,foo) if( (a!=None) and (b!=None) ): endNeighb = endNeighb+1 - # add to remove list - if( startNeighb < endNeighb ): - rem1.append(iStart) - rem2.append(jStart) - else: - rem1.append(iEnd) - rem2.append(jEnd) + # add to remove list + if( startNeighb < endNeighb ): + rem1.append(iStart) + rem2.append(jStart) + else: + rem1.append(iEnd) + rem2.append(jEnd) # remove for i,j in zip(rem1,rem2): - n1.remove(i) - n2.remove(j) + n1.remove(i) + n2.remove(j) return(n1,n2) def getList12(mol,n): dict12 = {} for a1 in mol.GetAtoms(): - iStart1 = a1.GetIdx() - if iStart1 not in n: - continue - neighbours1 = a1.GetNeighbors() - for a2 in neighbours1: # 1-2 - iEnd2 = a2.GetIdx() - if iEnd2 not in n: - continue - if iEnd2 == iStart1: - continue - if iStart1 in dict12.keys(): + iStart1 = a1.GetIdx() + if iStart1 not in n: + continue + neighbours1 = a1.GetNeighbors() + for a2 in neighbours1: # 1-2 + iEnd2 = a2.GetIdx() + if iEnd2 not in n: + continue + if iEnd2 == iStart1: + continue + if iStart1 in list(dict12.keys()): if iEnd2 not in dict12[iStart1]: - dict12[iStart1].append(iEnd2) - else: - dict12[iStart1] = [iEnd2] + dict12[iStart1].append(iEnd2) + else: + dict12[iStart1] = [iEnd2] return(dict12) def getList13(mol,n): dict13 = {} for a1 in mol.GetAtoms(): - iStart1 = a1.GetIdx() + iStart1 = a1.GetIdx() if iStart1 not in n: continue - neighbours1 = a1.GetNeighbors() - for a2 in neighbours1: # 1-2 - i2 = a2.GetIdx() + neighbours1 = a1.GetNeighbors() + for a2 in neighbours1: # 1-2 + i2 = a2.GetIdx() # if i2 not in n: # continue - if i2 == iStart1: - continue - neighbours2 = a2.GetNeighbors() - for a3 in neighbours2: # 1-3 - iEnd3 = a3.GetIdx() - if iEnd3 not in n: - continue - if (iEnd3==iStart1) or (iEnd3==i2): - continue - if iStart1 in dict13.keys(): + if i2 == iStart1: + continue + neighbours2 = a2.GetNeighbors() + for a3 in neighbours2: # 1-3 + iEnd3 = a3.GetIdx() + if iEnd3 not in n: + continue + if (iEnd3==iStart1) or (iEnd3==i2): + continue + if iStart1 in list(dict13.keys()): if iEnd3 not in dict13[iStart1]: - dict13[iStart1].append(iEnd3) - else: - dict13[iStart1] = [iEnd3] + dict13[iStart1].append(iEnd3) + else: + dict13[iStart1] = [iEnd3] return(dict13) def getList14(mol,n): dict14 = {} for a1 in mol.GetAtoms(): - iStart1 = a1.GetIdx() + iStart1 = a1.GetIdx() if iStart1 not in n: continue - neighbours1 = a1.GetNeighbors() - for a2 in neighbours1: # 1-2 - i2 = a2.GetIdx() + neighbours1 = a1.GetNeighbors() + for a2 in neighbours1: # 1-2 + i2 = a2.GetIdx() # if i2 not in n: # continue - if i2 == iStart1: - continue - neighbours2 = a2.GetNeighbors() - for a3 in neighbours2: # 1-3 - i3 = a3.GetIdx() -# if i3 not in n: -# continue - if (i3==iStart1) or (i3==i2): - continue + if i2 == iStart1: + continue + neighbours2 = a2.GetNeighbors() + for a3 in neighbours2: # 1-3 + i3 = a3.GetIdx() +# if i3 not in n: +# continue + if (i3==iStart1) or (i3==i2): + continue neighbours3 = a3.GetNeighbors() for a4 in neighbours3: # 1-4 iEnd4 = a4.GetIdx() - if iEnd4 not in n: - continue + if iEnd4 not in n: + continue if (iEnd4==iStart1) or (iEnd4==i2) or (iEnd4==i3): continue - if iStart1 in dict14.keys(): + if iStart1 in list(dict14.keys()): if iEnd4 not in dict14[iStart1]: - dict14[iStart1].append(iEnd4) - else: - dict14[iStart1] = [iEnd4] + dict14[iStart1].append(iEnd4) + else: + dict14[iStart1] = [iEnd4] return(dict14) def findProblemsExclusions(n1,n2,dict_mol1,dict_mol2): rem_start = [] rem_end = [] - for iStart in dict_mol1.keys(): - for iEnd in dict_mol1[iStart]: - jStart,jEnd = getAttr(n1,n2,iStart,iEnd) - if( (jStart==None) or (jEnd==None) ): # mapped to a dummy, thus no worries - continue - if jStart in dict_mol2.keys(): - if jEnd not in dict_mol2[jStart]: - # maybe entry already exists - if ((jStart in rem_start) or (jStart in rem_end)) and ((jEnd in rem_start) or (jEnd in rem_end)): - continue - rem_start.append(jStart) - rem_end.append(jEnd) - elif jEnd not in dict_mol2.keys(): - # a weird situation that shouldn't happen - print "Warning: something wrong in the 1-2, 1-3 or 1-4 lists. Trying to proceed with the warning..." + for iStart in list(dict_mol1.keys()): + for iEnd in dict_mol1[iStart]: + jStart,jEnd = getAttr(n1,n2,iStart,iEnd) + if( (jStart==None) or (jEnd==None) ): # mapped to a dummy, thus no worries + continue + if jStart in list(dict_mol2.keys()): + if jEnd not in dict_mol2[jStart]: + # maybe entry already exists + if ((jStart in rem_start) or (jStart in rem_end)) and ((jEnd in rem_start) or (jEnd in rem_end)): + continue + rem_start.append(jStart) + rem_end.append(jEnd) + elif jEnd not in list(dict_mol2.keys()): + # a weird situation that shouldn't happen + print("Warning: something wrong in the 1-2, 1-3 or 1-4 lists. Trying to proceed with the warning...") rem_start.append(jStart) rem_end.append(jEnd) return(rem_start,rem_end) @@ -467,7 +467,7 @@ def fixProblemsExclusions(mol1,mol2,n1,n2,startList,endList): a,b = getAttr(n1,n2,iEnd,bar) if( (a!=None) and (b!=None) ): endNeighb = endNeighb+1 - elif( iEnd==bar ): # atom of interest + elif( iEnd==bar ): # atom of interest a,b = getAttr(n1,n2,iEnd,foo) if( (a!=None) and (b!=None) ): endNeighb = endNeighb+1 @@ -494,18 +494,18 @@ def checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy): # 2) identify problematic mappings # 3) fix the problems: discard the atom with fewer mapped neighbours - ####### 1-2 ######### + ####### 1-2 ######### # 1a) 1-2 lists dict12_mol1 = getList12(mol1,n1) dict12_mol2 = getList12(mol2,n2) - # 2a) identify problems 1-2; and + # 2a) identify problems 1-2; and # 3a) fix 1-2 rem12_mol2_start,rem12_mol2_end = findProblemsExclusions(n1,n2,dict12_mol1,dict12_mol2) # output: indeces of mol2 n2,n1 = fixProblemsExclusions(mol2,mol1,n2,n1,rem12_mol2_start,rem12_mol2_end) rem12_mol1_start,rem12_mol1_end = findProblemsExclusions(n2,n1,dict12_mol2,dict12_mol1) # output: indeces of mol1 n1,n2 = fixProblemsExclusions(mol1,mol2,n1,n2,rem12_mol1_start,rem12_mol1_end) - ####### 1-3 ######### + ####### 1-3 ######### # 1b) 1-3 lists dict13_mol1 = getList13(mol1,n1) dict13_mol2 = getList13(mol2,n2) @@ -516,11 +516,11 @@ def checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy): rem13_mol1_start,rem13_mol1_end = findProblemsExclusions(n2,n1,dict13_mol2,dict13_mol1) # output: indeces of mol1 n1,n2 = fixProblemsExclusions(mol1,mol2,n1,n2,rem13_mol1_start,rem13_mol1_end) - ####### 1-4 ######### + ####### 1-4 ######### # 1b) 1-4 lists dict14_mol1 = getList14(mol1,n1) dict14_mol2 = getList14(mol2,n2) - # 2b) identify problems 1-4 and + # 2b) identify problems 1-4 and # 3b) fix 1-4 rem14_mol2_start,rem14_mol2_end = findProblemsExclusions(n1,n2,dict14_mol1,dict14_mol2) # output: indeces of mol2 n2,n1 = fixProblemsExclusions(mol2,mol1,n2,n1,rem14_mol2_start,rem14_mol2_end) @@ -536,29 +536,29 @@ def checkMCSTop(mol1,mol2,n1,n2,bH2H,bH2heavy): # if a bond exists in only one substructure, # modify the mapping by discarding one atom participating in the unmatched bond # try to discard the atom with fewer mapped neighbours - + # mol1 bonds startList = [] endList = [] for b1 in mol1.GetBonds(): iStart = b1.GetBeginAtomIdx() iEnd = b1.GetEndAtomIdx() - jStart,jEnd = getAttr(n1,n2,iStart,iEnd) - if( (jStart!=None) and (jEnd!=None) ): # not dummies - bOk = False - for b2 in mol2.GetBonds(): - foo = b2.GetBeginAtomIdx() - bar = b2.GetEndAtomIdx() - if( foo==jStart and bar==jEnd ): - bOk = True - break - elif( foo==jEnd and bar==jStart ): - bOk = True - break - if(bOk == False): - startList.append(iStart) - endList.append(iEnd) -# return(bOk) + jStart,jEnd = getAttr(n1,n2,iStart,iEnd) + if( (jStart!=None) and (jEnd!=None) ): # not dummies + bOk = False + for b2 in mol2.GetBonds(): + foo = b2.GetBeginAtomIdx() + bar = b2.GetEndAtomIdx() + if( foo==jStart and bar==jEnd ): + bOk = True + break + elif( foo==jEnd and bar==jStart ): + bOk = True + break + if(bOk == False): + startList.append(iStart) + endList.append(iEnd) +# return(bOk) n1,n2 = checkTopRemove(mol1,mol2,n1,n2,startList,endList,bH2H,bH2heavy) # mol2 bonds @@ -569,7 +569,7 @@ def checkMCSTop(mol1,mol2,n1,n2,bH2H,bH2heavy): iEnd = b1.GetEndAtomIdx() jStart,jEnd = getAttr(n2,n1,iStart,iEnd) if( (jStart!=None) and (jEnd!=None) ): # not dummies - bOk = False + bOk = False for b2 in mol1.GetBonds(): foo = b2.GetBeginAtomIdx() bar = b2.GetEndAtomIdx() @@ -579,10 +579,10 @@ def checkMCSTop(mol1,mol2,n1,n2,bH2H,bH2heavy): elif( foo==jEnd and bar==jStart ): bOk = True break - if(bOk == False): + if(bOk == False): startList.append(iStart) endList.append(iEnd) -# return(bOk) +# return(bOk) n1,n2 = checkTopRemove(mol2,mol1,n2,n1,startList,endList) return(True) @@ -590,22 +590,22 @@ def checkMCSTop(mol1,mol2,n1,n2,bH2H,bH2heavy): def writeFormatPDB(fname,m,title="",nr=1): fp = open(fname,'w') for atom in m.atoms: - foo = cp.deepcopy(atom) - # chlorine - if( 'CL' in atom.name or 'Cl' in atom.name or 'cl' in atom.name ): - foo.name = "CL"#+" " - print >>fp, foo - # bromine + foo = cp.deepcopy(atom) + # chlorine + if( 'CL' in atom.name or 'Cl' in atom.name or 'cl' in atom.name ): + foo.name = "CL"#+" " + print(foo, file=fp) + # bromine elif( 'BR' in atom.name or 'Br' in atom.name or 'br' in atom.name ): foo.name = "BR"#+" " - print >>fp, foo + print(foo, file=fp) elif( len(atom.name) >= 4): # too long atom name foo = cp.deepcopy(atom) foo.name = foo.name[:3] - print >>fp, foo + print(foo, file=fp) else: - print >>fp, atom - print >>fp, 'ENDMDL' + print(atom, file=fp) + print('ENDMDL', file=fp) fp.close() # sys.exit(0) @@ -630,7 +630,7 @@ def reformatPDB(filename,num,randint=42): return(newname,atomNameID,sigmaHoleID) def restoreAtomNames(mol,atomNameID): - + for atom in mol.GetAtoms(): newname = atom.GetMonomerInfo().GetName() ind = atom.GetIdx()+1 @@ -643,10 +643,10 @@ def restoreAtomNames(mol,atomNameID): def write_pairs(n1,n2,pairsFilename): fp = open(pairsFilename,"w") for i1,i2 in zip(n1,n2): - foo = i1 + 1 - bar = i2 + 1 - fp.write("%s %s\n" % (foo,bar) ) - fp.close() + foo = i1 + 1 + bar = i2 + 1 + fp.write("%s %s\n" % (foo,bar) ) + fp.close() def calcScore(mol1,mol2,n1,n2,bH2H,bH2heavy): res = 0.0 @@ -654,11 +654,11 @@ def calcScore(mol1,mol2,n1,n2,bH2H,bH2heavy): nn2 = len(n2) res = (nn1+nn2)/2.0 if( bH2H==True or bH2heavy==True): # consider hydrogens - na1 = mol1.GetNumAtoms() - na2 = mol2.GetNumAtoms() + na1 = mol1.GetNumAtoms() + na2 = mol2.GetNumAtoms() else: # no hydrogens - na1 = mol1.GetNumHeavyAtoms() - na2 = mol2.GetNumHeavyAtoms() + na1 = mol1.GetNumHeavyAtoms() + na2 = mol2.GetNumHeavyAtoms() res = 1.0 - res/(na1+na2-res) return(res) @@ -668,25 +668,25 @@ def distance_based(mol1, mol2, d, id1=None, id2=None, calcOnly=False): # to choose one MCS out of many if(calcOnly==True): - dist = 0.0 + dist = 0.0 c1 = mol1.GetConformer() c2 = mol2.GetConformer() for ind1,ind2 in zip(id1,id2): pos1 = c1.GetAtomPosition(ind1) pos2 = c2.GetAtomPosition(ind2) - dist = dist + 0.1*pos1.Distance(pos2) # Angstroms in pdb files + dist = dist + 0.1*pos1.Distance(pos2) # Angstroms in pdb files return(dist) # o3a if(id1==None or id2==None): c1 = mol1.GetConformer() c2 = mol2.GetConformer() - for a1 in mol1.GetAtoms(): + for a1 in mol1.GetAtoms(): pos1 = c1.GetAtomPosition(a1.GetIdx()) - dd = d*10.0 # Angstroms in pdb files + dd = d*10.0 # Angstroms in pdb files keep1 = None keep2 = None - for a2 in mol2.GetAtoms(): + for a2 in mol2.GetAtoms(): pos2 = c2.GetAtomPosition(a2.GetIdx()) dist = pos1.Distance(pos2) if(dist < dd): @@ -695,27 +695,27 @@ def distance_based(mol1, mol2, d, id1=None, id2=None, calcOnly=False): keep2 = a2.GetIdx() if( (keep1 is not None) and (keep2 is not None) ): pairs1.append(keep1) - pairs2.append(keep2) - return(pairs1,pairs2) + pairs2.append(keep2) + return(pairs1,pairs2) # mcs for ind1 in id1: - c1 = mol1.GetConformer() - pos1 = c1.GetAtomPosition(ind1) - dd = d*10.0 # Angstroms in pdb files - keep1 = None - keep2 = None - for ind2 in id2: - c2 = mol2.GetConformer() - pos2 = c2.GetAtomPosition(ind2) - dist = pos1.Distance(pos2) - if(dist < dd): - dd = dist - keep1 = ind1 - keep2 = ind2 - if( (keep1 is not None) and (keep2 is not None) ): - pairs1.append(keep1) - pairs2.append(keep2) + c1 = mol1.GetConformer() + pos1 = c1.GetAtomPosition(ind1) + dd = d*10.0 # Angstroms in pdb files + keep1 = None + keep2 = None + for ind2 in id2: + c2 = mol2.GetConformer() + pos2 = c2.GetAtomPosition(ind2) + dist = pos1.Distance(pos2) + if(dist < dd): + dd = dist + keep1 = ind1 + keep2 = ind2 + if( (keep1 is not None) and (keep2 is not None) ): + pairs1.append(keep1) + pairs2.append(keep2) return(pairs1,pairs2) def chargesTypesMMFF(mol): @@ -733,8 +733,8 @@ def o3a_alignment(mol1, mol2, bH2H, bH2Hpolar, bH2heavy, bRingsOnly, sigmaHoleID # prepare molecules and parameters # #################################### if( bRingsOnly==True ): - submol1 = subMolRing(mol1) - submol2 = subMolRing(mol2) + submol1 = subMolRing(mol1) + submol2 = subMolRing(mol2) ################### #### now align #### ################### @@ -767,11 +767,11 @@ def o3a_alignment(mol1, mol2, bH2H, bH2Hpolar, bH2heavy, bRingsOnly, sigmaHoleID n1,n2 = matchRings(mol1,mol2,n1,n2) # checking possible issues with the 1-2, 1-3 and 1-4 interactions # this is done before the ringCheck and repeated after - n1,n2 = checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy) + n1,n2 = checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy) # do not break rings bBreakRings = False if( bBreakRings==False ): - print "Avoiding breaking rings.\n" + print("Avoiding breaking rings.\n") n1,n2 = matchFullRings(mol1,mol2,n1,n2) # sys.exit(0) # treat disconnected @@ -780,7 +780,7 @@ def o3a_alignment(mol1, mol2, bH2H, bH2Hpolar, bH2heavy, bRingsOnly, sigmaHoleID # n1 and n2 are not sorted by pairs at this point n1,n2 = sortInd(mol1,mol2,n1,n2) # checking possible issues with the 1-2, 1-3 and 1-4 interactions - n1,n2 = checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy) + n1,n2 = checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy) return(n1,n2,pyO3A) @@ -793,12 +793,12 @@ def matchRings(mol1,mol2,nfoo,nbar): a2 = mol2.GetAtomWithIdx(n2) # arom1 = a1.GetIsAromatic() # arom2 = a2.GetIsAromatic() - ring1 = a1.IsInRing() - ring2 = a2.IsInRing() - if(ring1==True and ring2==False): - continue - if(ring1==False and ring2==True): - continue + ring1 = a1.IsInRing() + ring2 = a2.IsInRing() + if(ring1==True and ring2==False): + continue + if(ring1==False and ring2==True): + continue newn1.append(n1) newn2.append(n2) @@ -810,38 +810,38 @@ def oneAtomInRing(mol1,mol2,n1,n2): newn1 = [] newn2 = [] for i,j in zip(n1,n2): - a1 = mol1.GetAtomWithIdx(i) - a2 = mol2.GetAtomWithIdx(j) + a1 = mol1.GetAtomWithIdx(i) + a2 = mol2.GetAtomWithIdx(j) ring1 = a1.IsInRing() ring2 = a2.IsInRing() - if( ring1==True and ring2==True ): - bonds1 = a1.GetBonds() - bonds2 = a2.GetBonds() - found = 0 - for b1 in bonds1: - id1 = b1.GetEndAtomIdx() - at1 = b1.GetEndAtom() - if( b1.GetEndAtomIdx()==i ): - id1 = b1.GetBeginAtomIdx() - at1 = b1.GetBeginAtom() - for b2 in bonds2: + if( ring1==True and ring2==True ): + bonds1 = a1.GetBonds() + bonds2 = a2.GetBonds() + found = 0 + for b1 in bonds1: + id1 = b1.GetEndAtomIdx() + at1 = b1.GetEndAtom() + if( b1.GetEndAtomIdx()==i ): + id1 = b1.GetBeginAtomIdx() + at1 = b1.GetBeginAtom() + for b2 in bonds2: id2 = b2.GetEndAtomIdx() at2 = b2.GetEndAtom() if( b2.GetEndAtomIdx()==j ): id2 = b2.GetBeginAtomIdx() at2 = b2.GetBeginAtom() - if(at1.IsInRing()==True and at2.IsInRing()==True): - if( (id1 in n1) and (id2 in n2) ): - found = 1 - break - if(found==1): - break - if(found==1): - newn1.append(i) - newn2.append(j) - else: - newn1.append(i) - newn2.append(j) + if(at1.IsInRing()==True and at2.IsInRing()==True): + if( (id1 in n1) and (id2 in n2) ): + found = 1 + break + if(found==1): + break + if(found==1): + newn1.append(i) + newn2.append(j) + else: + newn1.append(i) + newn2.append(j) return(newn1,newn2) # this routine marks ring/non-ring atoms differently every time @@ -849,26 +849,26 @@ def oneAtomInRing(mol1,mol2,n1,n2): # non-ring: 7 def carbonize_rings(mol, bH2heavy=False, bRingsOnly=None): for atom in mol.GetAtoms(): - if(atom.GetAtomicNum() != 1): + if(atom.GetAtomicNum() != 1): if atom.IsInRing()==True: atom.SetAtomicNum(6) else: atom.SetAtomicNum(7) - elif(bH2heavy == True): - atom.SetAtomicNum(7) + elif(bH2heavy == True): + atom.SetAtomicNum(7) def carbonizeCrippen(mol, bH2heavy=False, bRingsOnly=None): crippen = [] for atom in mol.GetAtoms(): if(atom.GetAtomicNum() != 1): - foo = (0.1441,2.503) + foo = (0.1441,2.503) crippen.append(foo) elif(bH2heavy == True): foo = (0.1441,2.503) crippen.append(foo) if( (bRingsOnly!=None) and (atom.IsInRing()==False) ): foo = (bRingsOnly*(-1),bRingsOnly) - crippen.append(foo) + crippen.append(foo) return(crippen) def getBondLength(mol,id1,id2): @@ -883,19 +883,19 @@ def isTriple(mol,a): # analyze C,N (S not considered, because somewhat exotic) atoms for triple bonds # C if( a.GetAtomicNum()==6 ): - if( len(a.GetNeighbors())==2 ): - for neighb in a.GetNeighbors(): - if( neighb.GetAtomicNum()==7 ): - if( len(neighb.GetNeighbors())==1 ): - bTriple=True - if( neighb.GetAtomicNum()==6 ): - if( len(neighb.GetNeighbors())==2 ): - if( getBondLength(mol,a.GetIdx(),neighb.GetIdx())<1.25 ): # need to check bond length (in Angstroms) - bTriple=True + if( len(a.GetNeighbors())==2 ): + for neighb in a.GetNeighbors(): + if( neighb.GetAtomicNum()==7 ): + if( len(neighb.GetNeighbors())==1 ): + bTriple=True + if( neighb.GetAtomicNum()==6 ): + if( len(neighb.GetNeighbors())==2 ): + if( getBondLength(mol,a.GetIdx(),neighb.GetIdx())<1.25 ): # need to check bond length (in Angstroms) + bTriple=True # N elif( a.GetAtomicNum()==7 ): - if( len(a.GetNeighbors())==1 ): - bTriple=True + if( len(a.GetNeighbors())==1 ): + bTriple=True # Chem.MolToMolFile(mol1,"foomol.mol") # foo = Chem.MolFromMolFile("foomol.mol") @@ -925,14 +925,14 @@ def removePolarHmappings(mol1,mol2,nfoo,nbar,bH2Hpolar): a2 = mol2.GetAtomWithIdx(n2) anum1 = a1.GetAtomicNum() anum2 = a2.GetAtomicNum() - + # remove polar H mappings bPolar1 = False bPolar2 = False if anum1==1: bPolar1 = isPolarH( a1 ) if anum2==1: - bPolar2 = isPolarH( a2 ) + bPolar2 = isPolarH( a2 ) if(bPolar1==True or bPolar2==True): continue @@ -949,11 +949,11 @@ def tripleBond(mol1,mol2,nfoo,nbar): for n1,n2 in zip(nfoo,nbar): a1 = mol1.GetAtomWithIdx(n1) a2 = mol2.GetAtomWithIdx(n2) - bTriple1 = False - bTriple2 = False - # identify if bTriple is True/False - bTriple1 = isTriple(mol1,a1) - bTriple2 = isTriple(mol2,a2) + bTriple1 = False + bTriple2 = False + # identify if bTriple is True/False + bTriple1 = isTriple(mol1,a1) + bTriple2 = isTriple(mol2,a2) if(bTriple1==True and bTriple2==False): continue elif(bTriple2==True and bTriple1==False): @@ -992,15 +992,15 @@ def mapH( mol1, mol2, nfoo, nbar, bH2Hpolar ): def removeH(mol1,mol2,nfoo,nbar,bH2H,bH2Hpolar,bH2heavy): newn1 = [] - newn2 = [] + newn2 = [] for n1,n2 in zip(nfoo,nbar): - a1 = mol1.GetAtomWithIdx(n1) - a2 = mol2.GetAtomWithIdx(n2) - id1 = a1.GetAtomicNum() - id2 = a2.GetAtomicNum() + a1 = mol1.GetAtomWithIdx(n1) + a2 = mol2.GetAtomWithIdx(n2) + id1 = a1.GetAtomicNum() + id2 = a2.GetAtomicNum() bPolar1 = False bPolar2 = False - if( id1==1 and id2==1): + if( id1==1 and id2==1): bPolar1 = isPolarH( a1 ) bPolar2 = isPolarH( a2 ) if(bPolar1==True and bPolar2==True): @@ -1008,10 +1008,10 @@ def removeH(mol1,mol2,nfoo,nbar,bH2H,bH2Hpolar,bH2heavy): continue elif( bH2H==False ): continue - elif(bH2heavy==False and ( (id1==1) ^ (id2==1) ) ): # ^ := xor - continue - newn1.append(n1) - newn2.append(n2) + elif(bH2heavy==False and ( (id1==1) ^ (id2==1) ) ): # ^ := xor + continue + newn1.append(n1) + newn2.append(n2) return(newn1,newn2) def subMolByIndex(mol,ind): @@ -1054,13 +1054,13 @@ def calcRMSD(mol1,mol2,ind1,ind2): c1 = mol1.GetConformer() c2 = mol2.GetConformer() for id1 in ind1: - pos1 = c1.GetAtomPosition(id1) - toAdd = 999.999 - for id2 in ind2: - pos2 = c2.GetAtomPosition(id2) - if(pos1.Distance(pos2)1: - print "WARNING: the mapping may (but not necessarily) contain disconnected fragments. Proceed with caution." - return(ind1,ind2) -# return(n1_orig,n2_orig) + if len(ind1)>1: + print("WARNING: the mapping may (but not necessarily) contain disconnected fragments. Proceed with caution.") + return(ind1,ind2) +# return(n1_orig,n2_orig) n1_list = pp.GetMatches(subMol1) n2_list = pp.GetMatches(subMol2) # remove all matched hydrogens accordingly @@ -1103,12 +1103,12 @@ def disconnectedMCS(mol1,mol2,ind1,ind2,bH2H=True,bH2Hpolar=True,bH2heavy=True): # find out which of the generated list pairs has the smallest rmsd minRMSD = 999999.99 for nl1 in n1_list: - for nl2 in n2_list: - rmsd = calcRMSD(subMol1,subMol2,nl1,nl2) - if(rmsd < minRMSD): - minRMSD = rmsd - n1 = nl1 - n2 = nl2 + for nl2 in n2_list: + rmsd = calcRMSD(subMol1,subMol2,nl1,nl2) + if(rmsd < minRMSD): + minRMSD = rmsd + n1 = nl1 + n2 = nl2 # match indices n1,n2 to the original molecule ind1,ind2 n1_orig = matchIDbyRMSD(subMol1,n1,mol1) n2_orig = matchIDbyRMSD(subMol2,n2,mol2) @@ -1155,23 +1155,23 @@ def disconnectedRecursive(mol1,mol2,ind1,ind2): matchDict1 = {} matchDict2 = {} for id1,id2 in zip(ind1,ind2): - # find id1 - key1 = '' - for i in range(0,len(n1_fragments)): - if id1 in n1_fragments[i]: - key1 = str(i) - break - # find id2 - key2 = '' - for i in range(0,len(n2_fragments)): - if id2 in n2_fragments[i]: - key2 = str(i) - break - key = key1+'_'+key2 - if key in matchDict1.keys(): + # find id1 + key1 = '' + for i in range(0,len(n1_fragments)): + if id1 in n1_fragments[i]: + key1 = str(i) + break + # find id2 + key2 = '' + for i in range(0,len(n2_fragments)): + if id2 in n2_fragments[i]: + key2 = str(i) + break + key = key1+'_'+key2 + if key in list(matchDict1.keys()): matchDict1[key].append(id1) matchDict2[key].append(id2) - else: + else: matchDict1[key] = [id1] matchDict2[key] = [id2] ################################## @@ -1180,19 +1180,19 @@ def disconnectedRecursive(mol1,mol2,ind1,ind2): minMatchRMSD = 99999.999 maxMatchKey = '' for key in matchDict1: - if len(matchDict1[key]) > maxMatchSize: - maxMatchSize = len(matchDict1[key]) - maxMatchKey = key - minMatchRMSD = Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(matchDict2[key],matchDict1[key])) - elif len(matchDict1[key]) == maxMatchSize: - rmsd = Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(matchDict2[key],matchDict1[key])) - if rmsd < minMatchRMSD: - minMatchRMSD = rmsd - maxMatchKey = key + if len(matchDict1[key]) > maxMatchSize: + maxMatchSize = len(matchDict1[key]) + maxMatchKey = key + minMatchRMSD = Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=list(zip(matchDict2[key],matchDict1[key]))) + elif len(matchDict1[key]) == maxMatchSize: + rmsd = Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=list(zip(matchDict2[key],matchDict1[key]))) + if rmsd < minMatchRMSD: + minMatchRMSD = rmsd + maxMatchKey = key ######################### ######## output ######### if maxMatchKey == '': - return([],[]) + return([],[]) return(matchDict1[maxMatchKey],matchDict2[maxMatchKey]) def sortInd(mol1,mol2,ind1,ind2): @@ -1201,16 +1201,16 @@ def sortInd(mol1,mol2,ind1,ind2): c1 = mol1.GetConformer() c2 = mol2.GetConformer() for id1 in ind1: - pos1 = c1.GetAtomPosition(id1) - minDist = 9999.999 - keep = -1 - for id2 in ind2: - pos2 = c2.GetAtomPosition(id2) + pos1 = c1.GetAtomPosition(id1) + minDist = 9999.999 + keep = -1 + for id2 in ind2: + pos2 = c2.GetAtomPosition(id2) if(pos1.Distance(pos2) res): - res = len(l) + if(len(l) > res): + res = len(l) return(res) def genFilename(filename,counter): if(counter == 0): - name = filename + name = filename else: - name = os.path.splitext(filename)[0]+"_"+str(counter)+os.path.splitext(filename)[1] + name = os.path.splitext(filename)[0]+"_"+str(counter)+os.path.splitext(filename)[1] return(name) def incrementByOne(foo): bar = [] for l in foo: - l = l+1 - bar.append(l) + l = l+1 + bar.append(l) return(bar) def mcsHremove(mol1,mol2,n1_list,n2_list,bH2H,bH2Hpolar,bH2heavy): n1 = [] n2 = [] for nfoo in n1_list: - for nbar in n2_list: + for nbar in n2_list: foo,bar = removeH(mol1,mol2,nfoo,nbar,bH2H,bH2Hpolar,bH2heavy) - n1.append(foo) - n2.append(bar) + n1.append(foo) + n2.append(bar) return(n1,n2) def mcsHmap( mol1, mol2, n1_list, n2_list, bH2Hpolar ): @@ -1295,46 +1295,46 @@ def mcsDist(mol1,mol2,n1_list,n2_list,d,bH2H,bH2heavy): # distances maxMCS = 0 # size of the largest MCS fulfilling the distances for nfoo,nbar in zip(n1_list,n2_list): - alignID = zip(nfoo,nbar) + alignID = list(zip(nfoo,nbar)) ########################################## ###### o3a alignment may work better ##### - rmsd = Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(nbar,nfoo)) -# rmsd = alignOnSubset(mol1,mol2,alignID) # but it has some dependence on the molecule sequence, not sure if I trust it + rmsd = Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=list(zip(nbar,nfoo))) +# rmsd = alignOnSubset(mol1,mol2,alignID) # but it has some dependence on the molecule sequence, not sure if I trust it # print "RMSD after alignment: %f Angstroms" %rmsd x,y = distance_based(mol1,mol2,d,nfoo,nbar) - n1.append(x) - n2.append(y) - if(len(x)>maxMCS): - maxMCS = len(x) - + n1.append(x) + n2.append(y) + if(len(x)>maxMCS): + maxMCS = len(x) + nn1 = [] nn2 = [] # match rings and remove disconnected maxMCS = 0 for nfoo,nbar in zip(n1,n2): - # rings + # rings x,y = matchRings(mol1,mol2,nfoo,nbar) - # disconnected - #x,y = disconnectedMCS(mol1,mol2,x,y,bH2H,bH2heavy) - x,y = disconnectedRecursive(mol1,mol2,x,y) - nn1.append(x) - nn2.append(y) + # disconnected + #x,y = disconnectedMCS(mol1,mol2,x,y,bH2H,bH2heavy) + x,y = disconnectedRecursive(mol1,mol2,x,y) + nn1.append(x) + nn2.append(y) if(len(x)>maxMCS): maxMCS = len(x) - - print "maxMCS after distance treatment: %d" % maxMCS + + print("maxMCS after distance treatment: %d" % maxMCS) n1 = [] n2 = [] # only keep the largest MCSs maxSize = getLargestList(nn1+nn2) for nfoo,nbar in zip(nn1,nn2): - if(len(nfoo)==maxSize and len(nbar)==maxSize): - n1.append(nfoo) - n2.append(nbar) -# print "foo",nfoo,nbar + if(len(nfoo)==maxSize and len(nbar)==maxSize): + n1.append(nfoo) + n2.append(nbar) +# print "foo",nfoo,nbar return(n1,n2) - + def selectOneMCS(n1_list,n2_list,mol1,mol2): if len(n1_list)==0 or len(n2_list)==0: return([],[]) @@ -1360,8 +1360,8 @@ def selectOneMCS(n1_list,n2_list,mol1,mol2): for nfoo,nbar in zip(n1_largest,n2_largest): bOK = True for i,j in zip(nfoo,nbar): - a1 = mol1.GetAtomWithIdx(i) - a2 = mol2.GetAtomWithIdx(j) + a1 = mol1.GetAtomWithIdx(i) + a2 = mol2.GetAtomWithIdx(j) if a1.IsInRing()==True and a2.IsInRing()==False: bOK = False break @@ -1375,18 +1375,18 @@ def selectOneMCS(n1_list,n2_list,mol1,mol2): # of the largest ones select the minRMSD rmsdMin = 9999.999 for nfoo,nbar in zip(n1_largestB,n2_largestB): - # align - alignID = zip(nbar,nfoo) - try: + # align + alignID = list(zip(nbar,nfoo)) + try: rmsd = Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=alignID) - except: - rmsd = rmsdMin*10.0 + except: + rmsd = rmsdMin*10.0 # x,y = distance_based(mol1,mol2,d,nfoo,nbar,True) - # compare + # compare if( rmsd < rmsdMin ): - rmsdMin = rmsd - n1 = nfoo - n2 = nbar + rmsdMin = rmsd + n1 = nfoo + n2 = nbar return(n1,n2) def checkSingleAtomInRingMap( rem1,n1,n2,mol1,mol2,r1,r2,dontRem1,dontRem2 ): @@ -1399,7 +1399,7 @@ def checkSingleAtomInRingMap( rem1,n1,n2,mol1,mol2,r1,r2,dontRem1,dontRem2 ): ring2 = a2.IsInRing() identifiedRings = [] if ring1==False and ring2==True: - for ar2 in r2:#.AtomRings(): # go over the rings + for ar2 in r2:#.AtomRings(): # go over the rings for at2 in ar2: # go over atoms # print "vg ",i,ar2,at2,j if at2==j: # found a ring of interest @@ -1416,7 +1416,7 @@ def checkSingleAtomInRingMap( rem1,n1,n2,mol1,mol2,r1,r2,dontRem1,dontRem2 ): for ring2 in identifiedRings: # print "vg ",ring2 bFoo,mappedInd = countMapped( ring2,n2 ) -# print "vg ",bFoo,mappedInd,len(mappedInd) +# print "vg ",bFoo,mappedInd,len(mappedInd) if len(mappedInd)>1: # print "HERE" bRem = True @@ -1433,7 +1433,7 @@ def checkSingleAtomInRingMap( rem1,n1,n2,mol1,mol2,r1,r2,dontRem1,dontRem2 ): if bRem==False: # do not need to remove these atoms dontRem1.append(i) dontRem2.append(j) - + def matchFullRings(mol1,mol2,n1,n2): n1_init = cp.deepcopy(n1) @@ -1454,31 +1454,31 @@ def matchFullRings(mol1,mol2,n1,n2): a2 = mol2.GetAtomWithIdx(j) ring1 = a1.IsInRing() ring2 = a2.IsInRing() - if( (ring1==True) and (ring2==False) ): - rem1.append(i) - rem2.append(j) + if( (ring1==True) and (ring2==False) ): + rem1.append(i) + rem2.append(j) elif( (ring1==False) and (ring2==True) ): - rem1.append(i) - rem2.append(j) + rem1.append(i) + rem2.append(j) elif( (ring1==True) and (ring2==True) ): - mapped1 = False - mapped2 = False + mapped1 = False + mapped2 = False # here only checking if, given one morphable atom in a ring, # is there at least one ring which would harbor this atom # and all the other atoms in that ring would also be morphable - for ar1 in r1:#.AtomRings(): - if( i in ar1 ): - mapped1 = isMapped(ar1,n1) - if( mapped1 == True): - break + for ar1 in r1:#.AtomRings(): + if( i in ar1 ): + mapped1 = isMapped(ar1,n1) + if( mapped1 == True): + break for ar2 in r2:#.AtomRings(): - if( j in ar2 ): + if( j in ar2 ): mapped2 = isMapped(ar2,n2) if( mapped2 == True): break - if( (mapped1==False) or (mapped2==False) ): - rem1.append(i) - rem2.append(j) + if( (mapped1==False) or (mapped2==False) ): + rem1.append(i) + rem2.append(j) # before removing, check for a special case: # a single non-ring atom could be allowed to map to a single ring atom @@ -1541,10 +1541,10 @@ def matchFullRings(mol1,mol2,n1,n2): n1_out,n2_out = removeInd( n1,n2,minRem,minRemB ) # print n1,minRem break - if minRemSize>0 and minRemSize<999: + if minRemSize>0 and minRemSize<999: continue # sys.exit(0) - + # go over the rings in the second molecule for ar2 in r2:#.AtomRings(): bRem2,mappedInd = countMapped(ar2,n2) @@ -1575,10 +1575,10 @@ def matchFullRings(mol1,mol2,n1,n2): # remove the atoms n1_out,n2_out = removeInd( n1,n2,minRemB,minRem ) break - if minRemSize>0 and minRemSize<999: + if minRemSize>0 and minRemSize<999: continue - bFound = False + bFound = False ########################################################## @@ -1588,29 +1588,29 @@ def matchFullRings(mol1,mol2,n1,n2): n1_return = [] # list of atoms to return to the mapping n2_return = [] # list of atoms to return to the mapping for i,j in zip(n1_init,n2_init): # these *_init lists are prior to ring processing - if (i not in n1_out) and (j not in n2_out): # a mapping was removed by ring processing - a1 = mol1.GetAtomWithIdx(i) - a2 = mol2.GetAtomWithIdx(j) - ring1 = a1.IsInRing() - ring2 = a2.IsInRing() - if( (ring1==True) and (ring2==True) ): - neighbors1 = a1.GetNeighbors() - neighbors2 = a2.GetNeighbors() - bOK1 = False - bOK2 = False - for nn1 in neighbors1: - nnind1 = nn1.GetIdx() - if nnind1 in n1_out: - bOK1 = True - break - for nn2 in neighbors2: - nnind2 = nn2.GetIdx() - if nnind2 in n2_out: - bOK2 = True - break - if bOK1==True and bOK2==True: - n1_return.append(i) - n2_return.append(j) + if (i not in n1_out) and (j not in n2_out): # a mapping was removed by ring processing + a1 = mol1.GetAtomWithIdx(i) + a2 = mol2.GetAtomWithIdx(j) + ring1 = a1.IsInRing() + ring2 = a2.IsInRing() + if( (ring1==True) and (ring2==True) ): + neighbors1 = a1.GetNeighbors() + neighbors2 = a2.GetNeighbors() + bOK1 = False + bOK2 = False + for nn1 in neighbors1: + nnind1 = nn1.GetIdx() + if nnind1 in n1_out: + bOK1 = True + break + for nn2 in neighbors2: + nnind2 = nn2.GetIdx() + if nnind2 in n2_out: + bOK2 = True + break + if bOK1==True and bOK2==True: + n1_return.append(i) + n2_return.append(j) # return what has been found for i,j in zip(n1_return,n2_return): bOK1 = False @@ -1640,19 +1640,19 @@ def matchFullRings(mol1,mol2,n1,n2): n1_return = [] # list of atoms to return to the mapping n2_return = [] # list of atoms to return to the mapping for i,j in zip(n1_init,n2_init): # these *_init lists are prior to ring processing - if (i not in n1_out) and (j not in n2_out): # a mapping was removed by ring processing - a1 = mol1.GetAtomWithIdx(i) - a2 = mol2.GetAtomWithIdx(j) - ring1 = a1.IsInRing() - ring2 = a2.IsInRing() - if( ( (ring1==True) and (ring2==False) ) or ( (ring1==False) and (ring2==True) ) ): - neighbors1 = a1.GetNeighbors() # it is sufficient to check for one of the molecules - for nn1 in neighbors1: - nnind1 = nn1.GetIdx() - if nnind1 in n1_out: - n1_return.append(i) - n2_return.append(j) - break + if (i not in n1_out) and (j not in n2_out): # a mapping was removed by ring processing + a1 = mol1.GetAtomWithIdx(i) + a2 = mol2.GetAtomWithIdx(j) + ring1 = a1.IsInRing() + ring2 = a2.IsInRing() + if( ( (ring1==True) and (ring2==False) ) or ( (ring1==False) and (ring2==True) ) ): + neighbors1 = a1.GetNeighbors() # it is sufficient to check for one of the molecules + for nn1 in neighbors1: + nnind1 = nn1.GetIdx() + if nnind1 in n1_out: + n1_return.append(i) + n2_return.append(j) + break # print "VG",n1_return # return what has been found for i,j in zip(n1_return,n2_return): @@ -1689,9 +1689,9 @@ def countMapped(ring,ind): def isMapped(ring,ind): for a in ring: if( a in ind): - continue - else: - return(False) + continue + else: + return(False) return(True) @@ -1701,27 +1701,27 @@ def nullHydrogens(mol): def carbonizeOLD(mol, bH2heavy=False, bRingsOnly=None): for atom in mol.GetAtoms(): - if(atom.GetAtomicNum() != 1): - atom.SetAtomicNum(6) - elif(bH2heavy == True): - atom.SetAtomicNum(6) - if( (bRingsOnly!=None) and (atom.IsInRing()==False) ): - atom.SetAtomicNum(bRingsOnly) + if(atom.GetAtomicNum() != 1): + atom.SetAtomicNum(6) + elif(bH2heavy == True): + atom.SetAtomicNum(6) + if( (bRingsOnly!=None) and (atom.IsInRing()==False) ): + atom.SetAtomicNum(bRingsOnly) def carbonize(mol, hnum, bH2heavy=False, bRingsOnly=None): if bH2heavy==True: hnum = 6 for atom in mol.GetAtoms(): - if(atom.GetAtomicNum() != 1): - atom.SetAtomicNum(6) + if(atom.GetAtomicNum() != 1): + atom.SetAtomicNum(6) if atom.IsInRing()==True: - atom.SetAtomicNum(7) - else: + atom.SetAtomicNum(7) + else: atom.SetAtomicNum( hnum ) - if( (bRingsOnly!=None) and (atom.IsInRing()==False) ): - atom.SetAtomicNum(bRingsOnly) + if( (bRingsOnly!=None) and (atom.IsInRing()==False) ): + atom.SetAtomicNum(bRingsOnly) def carbonizeHonly( mol, hnum ): for atom in mol.GetAtoms(): @@ -1741,7 +1741,7 @@ def mcs(mol1, mol2, molForMcs1,molForMcs2, bH2H, bH2Hpolar, bH2heavy, bdMCS, bRi carbonize(bar,hnum2,bH2heavy,43) elif( bCarbonize==True ): carbonize(foo,hnum1,bH2heavy) - carbonize(bar,hnum2,bH2heavy) + carbonize(bar,hnum2,bH2heavy) elif( bH2heavy==False ): # only change hydrogen numbering carbonizeHonly( foo, hnum1 ) carbonizeHonly( bar, hnum2 ) @@ -1753,7 +1753,7 @@ def mcs(mol1, mol2, molForMcs1,molForMcs2, bH2H, bH2Hpolar, bH2heavy, bdMCS, bRi # sys.exit(0) mols = [foo,bar] - print "Searching..." + print("Searching...") # res = MCS.FindMCS(mols,ringMatchesRingOnly=True, completeRingsOnly=True, atomCompare='elements', bondCompare='any', timeout=int(t), maximize='bonds') # for new RDKit-2018 use below if bElements==True: @@ -1770,7 +1770,7 @@ def mcs(mol1, mol2, molForMcs1,molForMcs2, bH2H, bH2Hpolar, bH2heavy, bdMCS, bRi return(n1_list,n2_list) n1_list = pp.GetMatches(foo) n2_list = pp.GetMatches(bar) - print 'Found %d MCSs in total (mol1: %d, mol2: %d), each with %d atoms and %d bonds' % (len(n1_list)*len(n2_list),len(n1_list),len(n2_list),res.numAtoms,res.numBonds) + print('Found %d MCSs in total (mol1: %d, mol2: %d), each with %d atoms and %d bonds' % (len(n1_list)*len(n2_list),len(n1_list),len(n2_list),res.numAtoms,res.numBonds)) #### OLD #### # if hydrogens to be removed @@ -1790,9 +1790,9 @@ def mcs(mol1, mol2, molForMcs1,molForMcs2, bH2H, bH2Hpolar, bH2heavy, bdMCS, bRi for n1,n2 in zip(n1_list,n2_list): # n1,n2 = tripleBond(mol1,mol2,n1,n2) n1,n2 = checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy) - n1,n2 = disconnectedRecursive(mol1,mol2,n1,n2) - n1_foo.append(n1) - n2_foo.append(n2) + n1,n2 = disconnectedRecursive(mol1,mol2,n1,n2) + n1_foo.append(n1) + n2_foo.append(n2) n1_list = cp.copy(n1_foo) n2_list = cp.copy(n2_foo) @@ -1800,21 +1800,21 @@ def mcs(mol1, mol2, molForMcs1,molForMcs2, bH2H, bH2Hpolar, bH2heavy, bdMCS, bRi # test # for n1,n2 in zip(n1_list,n2_list): # print "foo" -# for i1,i2 in zip(n1,n2): -# print i1+1,i2+1 -# print "\n"; +# for i1,i2 in zip(n1,n2): +# print i1+1,i2+1 +# print "\n"; # sys.exit(0) ############################################# ######### chirality check ################### # bChiral = True#False#True if( bChiral==True ): - print "Chirality check." + print("Chirality check.") n1_foo = [] n2_foo = [] for n1,n2 in zip(n1_list,n2_list): - while(bCheckChiralViolation(mol1,mol2,n1,n2)==True): + while(bCheckChiralViolation(mol1,mol2,n1,n2)==True): n1,n2 = checkChiral(mol1,mol2,n1,n2) - n1,n2 = disconnectedRecursive(mol1,mol2,n1,n2) + n1,n2 = disconnectedRecursive(mol1,mol2,n1,n2) n1_foo.append(n1) n2_foo.append(n2) n1_list = cp.copy(n1_foo) @@ -1825,7 +1825,7 @@ def mcs(mol1, mol2, molForMcs1,molForMcs2, bH2H, bH2Hpolar, bH2heavy, bdMCS, bRi n1_foo = [] n2_foo = [] for n1,n2 in zip(n1_list,n2_list): - n1,n2 = checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy) + n1,n2 = checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy) n1_foo.append(n1) n2_foo.append(n2) n1_list = cp.copy(n1_foo) @@ -1835,7 +1835,7 @@ def mcs(mol1, mol2, molForMcs1,molForMcs2, bH2H, bH2Hpolar, bH2heavy, bdMCS, bRi ######### do not break rings ################ bBreakRings = False if( bBreakRings==False ): - print "Avoiding breaking rings." + print("Avoiding breaking rings.") n1_foo = [] n2_foo = [] for n1,n2 in zip(n1_list,n2_list): @@ -1848,26 +1848,26 @@ def mcs(mol1, mol2, molForMcs1,molForMcs2, bH2H, bH2Hpolar, bH2heavy, bdMCS, bRi # test # for n1,n2 in zip(n1_list,n2_list): # print "foo" -# for i1,i2 in zip(n1,n2): -# print i1+1,i2+1 -# print "\n"; +# for i1,i2 in zip(n1,n2): +# print i1+1,i2+1 +# print "\n"; # sys.exit(0) # if distances to be compared if(bdMCS==True): - n1_list,n2_list = mcsDist(mol1,mol2,n1_list,n2_list,d,bH2H,bH2heavy) - # due to meeting distance criterium - # the rings may be broken - # and disconnected fragments may appear - bBreakRings = False - if( bBreakRings==False ): - print "Avoiding breaking rings after meeting distance criterium.\n" + n1_list,n2_list = mcsDist(mol1,mol2,n1_list,n2_list,d,bH2H,bH2heavy) + # due to meeting distance criterium + # the rings may be broken + # and disconnected fragments may appear + bBreakRings = False + if( bBreakRings==False ): + print("Avoiding breaking rings after meeting distance criterium.\n") n1_foo = [] n2_foo = [] for n1,n2 in zip(n1_list,n2_list): n1,n2 = matchFullRings(mol1,mol2,n1,n2) - n1,n2 = disconnectedRecursive(mol1,mol2,n1,n2) + n1,n2 = disconnectedRecursive(mol1,mol2,n1,n2) n1_foo.append(n1) n2_foo.append(n2) n1_list = cp.copy(n1_foo) @@ -1877,29 +1877,29 @@ def mcs(mol1, mol2, molForMcs1,molForMcs2, bH2H, bH2Hpolar, bH2heavy, bdMCS, bRi n1,n2 = selectOneMCS(n1_list,n2_list,mol1,mol2) # one more final check for possible issues with the 1-2, 1-3 and 1-4 interactions - n1,n2 = checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy) + n1,n2 = checkTop(mol1,mol2,n1,n2,bH2H,bH2heavy) # remove sigma hole virtual particles n1,n2 = remove_sigmaHoles( n1,n2,sigmaHoleID1,sigmaHoleID2) - print 'Final MCS that survived after pruning: %d atoms' % (len(n1)) + print('Final MCS that survived after pruning: %d atoms' % (len(n1))) return n1,n2 def checkRingsOnlyFlag(mol1,mol2): flag = 0 for atom in mol1.GetAtoms(): - if(atom.IsInRing()==True): - flag = flag + 1 - break + if(atom.IsInRing()==True): + flag = flag + 1 + break for atom in mol2.GetAtoms(): if(atom.IsInRing()==True): flag = flag + 1 break if(flag==2): - return(True) + return(True) else: - return(False) + return(False) def main(argv): @@ -1931,11 +1931,11 @@ def main(argv): Option( "-H2heavy", "bool", "False", "should hydrogen be morphed into a heavy atom (also sets -H2H to true)"), Option( "-RingsOnly", "bool", "False", "should rings only be used in the MCS search or alignment"), Option( "-dMCS", "bool", "False", "find MCS, superimpose the structures based on the MCS, apply distance in\ - Cartesian coordinate space to define the morphes"), + Cartesian coordinate space to define the morphes"), Option( "-swap", "bool", "False", "also try swapping the molecule order (mainly as a cross-check, requires double time)"), Option( "-chirality", "bool", "True", "perform chirality check for MCS mapping"), Option( "-d", "float", "0.05", "distance (nm) between atoms to consider them morphable"), - Option( "-timeout", "int", "10", "maximum time (s) for an MCS search"), + Option( "-timeout", "int", "10", "maximum time (s) for an MCS search"), ] help_text = () @@ -1943,7 +1943,7 @@ def main(argv): # pass options, files and the command line to pymacs cmdl = Commandline( argv, options = options, fileoptions = files, program_desc = help_text, check_for_existing_files = False, version = "0.0" ) - + # deal with the flags bH2H = False bH2Hpolar = False @@ -1952,15 +1952,15 @@ def main(argv): bSwap = False timeout = None if(cmdl['-H2H']==True): - bH2H = True + bH2H = True if(cmdl['-H2Hpolar']==True): bH2Hpolar = True bH2heavy = False if(cmdl['-H2heavy']==True): bH2heavy = True - bH2H = True + bH2H = True if(cmdl.opt['-d'].is_set): - d = cmdl['-d'] + d = cmdl['-d'] timeout = int(cmdl['-timeout']) if(cmdl['-chirality']==False): bChiral = False @@ -1972,26 +1972,26 @@ def main(argv): bAlignment = True bMCS = True if cmdl.opt['-alignment'].is_set: - bAlignment = cmdl['-alignment'] - if cmdl['-alignment']==True: - if cmdl.opt['-mcs'].is_set and cmdl['-mcs']==False: - bMCS = False - if cmdl.opt['-mcs'].is_set==False: - bMCS = False - if cmdl.opt['-mcs'].is_set: - bMCS = cmdl['-mcs'] + bAlignment = cmdl['-alignment'] + if cmdl['-alignment']==True: + if cmdl.opt['-mcs'].is_set and cmdl['-mcs']==False: + bMCS = False + if cmdl.opt['-mcs'].is_set==False: + bMCS = False + if cmdl.opt['-mcs'].is_set: + bMCS = cmdl['-mcs'] if cmdl['-mcs']==True: if cmdl.opt['-alignment'].is_set and cmdl['-alignment']==False: bAlignment = False if cmdl.opt['-alignment'].is_set==False: bAlignment = False if bMCS==False and bAlignment==False: - print "No method (alignment, mcs) was selected." - sys.exit(0) - print "Morphable atoms will be identified using the following methods:" - print "Alignment: ",bAlignment - print "MCS: ",bMCS - print "\n" + print("No method (alignment, mcs) was selected.") + sys.exit(0) + print("Morphable atoms will be identified using the following methods:") + print("Alignment: ",bAlignment) + print("MCS: ",bMCS) + print("\n") ###################################### # read index @@ -2027,14 +2027,14 @@ def main(argv): molForMcs1 = cp.deepcopy(mol1) molForMcs2 = cp.deepcopy(mol2) try: - rdmolops.AssignAtomChiralTagsFromStructure(mol1) - rdmolops.AssignAtomChiralTagsFromStructure(mol2) + rdmolops.AssignAtomChiralTagsFromStructure(mol1) + rdmolops.AssignAtomChiralTagsFromStructure(mol2) molForMcs1 = cp.deepcopy(mol1) molForMcs2 = cp.deepcopy(mol2) - rdmolops.AssignStereochemistry(mol1) - rdmolops.AssignStereochemistry(mol2) + rdmolops.AssignStereochemistry(mol1) + rdmolops.AssignStereochemistry(mol2) except: - print "Chirality not assigned" + print("Chirality not assigned") # mol1 = Chem.SDMolSupplier(cmdl['-i1'],removeHs=False,sanitize=True) # mol2 = Chem.SDMolSupplier(cmdl['-i2'],removeHs=False,sanitize=True) @@ -2047,11 +2047,11 @@ def main(argv): bRingsOnly = False bYesRings = checkRingsOnlyFlag(mol1,mol2) if(cmdl['-RingsOnly']==True): - if( bYesRings==True ): - bRingsOnly=True - else: - print "-RingsOnly flag is unset, because one (or both) molecule has no rings\n" - + if( bYesRings==True ): + bRingsOnly=True + else: + print("-RingsOnly flag is unset, because one (or both) molecule has no rings\n") + n1 = [] n2 = [] @@ -2069,109 +2069,109 @@ def main(argv): n1mcs = [] n2mcs = [] if(bMCS==True): - print "The topology matching approach will be used (MCS)" - print "fmcs module: Copyright (c) 2012 Andrew Dalke Scientific AB\n" - if(bRingsOnly==True): - n1mcs,n2mcs = mcs(mol1,mol2,molForMcs1,molForMcs2,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],bRingsOnly,d,bChiral,sigmaHoleID1,sigmaHoleID2,timeout) - else: + print("The topology matching approach will be used (MCS)") + print("fmcs module: Copyright (c) 2012 Andrew Dalke Scientific AB\n") + if(bRingsOnly==True): + n1mcs,n2mcs = mcs(mol1,mol2,molForMcs1,molForMcs2,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],bRingsOnly,d,bChiral,sigmaHoleID1,sigmaHoleID2,timeout) + else: n1A = [] n2A = [] - print "\nTrying to run an MCS using all atoms: modified molecules, match elements..." + print("\nTrying to run an MCS using all atoms: modified molecules, match elements...") n1A,n2A = mcs(mol1,mol2,molForMcs1,molForMcs2,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],False,d,bChiral,sigmaHoleID1,sigmaHoleID2,timeout,bElements=True, bCarbonize=True) n1mcs = n1A n2mcs = n2A - print "Size of mapping: ",len(n1A) + print("Size of mapping: ",len(n1A)) - print "\nTrying to run an MCS using all atoms: unmodified molecules, match elements..." + print("\nTrying to run an MCS using all atoms: unmodified molecules, match elements...") n1B,n2B = mcs(mol1,mol2,molForMcs1,molForMcs2,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],False,d,bChiral,sigmaHoleID1,sigmaHoleID2,timeout,bElements=True, bCarbonize=False) - print "Size of mapping: ",len(n1B) + print("Size of mapping: ",len(n1B)) n1mcs,n2mcs = compare_mappings_by_size( mol1,mol2, n1mcs, n2mcs, n1B, n2B ) # print "\nTrying to run an MCS using all atoms: unmodified molecules, match any atom..." # n1C,n2C = mcs(mol1,mol2,molForMcs1,molForMcs2,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],False,d,bChiral,sigmaHoleID1,sigmaHoleID2,timeout,bElements=False, bCarbonize=False) -# print "Size of mapping: ",len(n1C) +# print "Size of mapping: ",len(n1C) # n1mcs,n2mcs = compare_mappings_by_size( mol1,mol2, n1mcs, n2mcs, n1C, n2C ) # print "\nTrying to run an MCS using all atoms: variant 4..." # n1D,n2D = mcs(mol1,mol2,molForMcs1,molForMcs2,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],False,d,bChiral,sigmaHoleID1,sigmaHoleID2,timeout,bElements=False, bCarbonize=True) -# print "Size of mapping: ",len(n1D) +# print "Size of mapping: ",len(n1D) # n1D = [] # n1mcs,n2mcs = compare_mappings_by_size( mol1,mol2, n1mcs, n2mcs, n1C, n2C ) - print "Using variant with the mapping size of ",len(n1mcs) + print("Using variant with the mapping size of ",len(n1mcs)) if( bYesRings==True ): - print "Trying to run an MCS using rings only..." + print("Trying to run an MCS using rings only...") n1B,n2B = mcs(mol1,mol2,molForMcs1,molForMcs2,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],True,d,bChiral,sigmaHoleID1,sigmaHoleID2,timeout) - n1mcs,n2mcs = compare_mappings_by_size( mol1,mol2, n1mcs, n2mcs, n1B, n2B ) - print "Using final MCS mapping of size ",len(n1mcs) + n1mcs,n2mcs = compare_mappings_by_size( mol1,mol2, n1mcs, n2mcs, n1B, n2B ) + print("Using final MCS mapping of size ",len(n1mcs)) if len(n1mcs)==0: - bMCSfailed = True + bMCSfailed = True ######################################## ####### alignment ###################### n1align = [] n2align = [] if( (bAlignment==True) or (bMCSfailed==True) ): - if bMCSfailed==True: - print "The MCS approach did not find any mapping" - print "\nThe alignment approach will be used" - print "Tosco, P., Balle, T. & Shiri, F. Open3DALIGN: an open-source software aimed at unsupervised ligand alignment. J Comput Aided Mol Des 25:777-83 (2011)" - print "Alignment is based on atom logP contributions: S. A. Wildman and G. M. Crippen JCICS _39_ 868-873 (1999)\n" - # only use rings - if(bRingsOnly==True): + if bMCSfailed==True: + print("The MCS approach did not find any mapping") + print("\nThe alignment approach will be used") + print("Tosco, P., Balle, T. & Shiri, F. Open3DALIGN: an open-source software aimed at unsupervised ligand alignment. J Comput Aided Mol Des 25:777-83 (2011)") + print("Alignment is based on atom logP contributions: S. A. Wildman and G. M. Crippen JCICS _39_ 868-873 (1999)\n") + # only use rings + if(bRingsOnly==True): n1align,n2align,pyO3A = o3a_alignment(mol1,mol2,bH2H,bH2Hpolar,bH2heavy,bRingsOnly,sigmaHoleID1,sigmaHoleID2,True,d) - # else try both options and choose better - else: - print "Trying to align all atoms..." + # else try both options and choose better + else: + print("Trying to align all atoms...") n1align,n2align,pyO3A = o3a_alignment(mol1,mol2,bH2H,bH2Hpolar,bH2heavy,False,sigmaHoleID1,sigmaHoleID2,True,d) - print "Size of mapping: ",len(n1align) - if( bYesRings==True ): - print "Trying to align rings only..." + print("Size of mapping: ",len(n1align)) + if( bYesRings==True ): + print("Trying to align rings only...") mol1 = cp.deepcopy(molcp1) mol2 = cp.deepcopy(molcp2) n1B,n2B,pyO3A = o3a_alignment(mol1,mol2,bH2H,bH2Hpolar,bH2heavy,True,sigmaHoleID1,sigmaHoleID2,True,d) - print "Size of mapping: ",len(n1B) - if(len(n1align)<=len(n1B)): - print "Using ring only alignment result.\n" - n1align = n1B - n2align = n2B - else: - print "Using all atom alignment result.\n" + print("Size of mapping: ",len(n1B)) + if(len(n1align)<=len(n1B)): + print("Using ring only alignment result.\n") + n1align = n1B + n2align = n2B + else: + print("Using all atom alignment result.\n") # select the better result: mcs or align if len(n1align)>=len(n1mcs): - print "The final result is based on the O3A alignment.\n" - n1 = n1align - n2 = n2align + print("The final result is based on the O3A alignment.\n") + n1 = n1align + n2 = n2align else: - print "The final result is based on the MCS.\n" - n1 = n1mcs - n2 = n2mcs + print("The final result is based on the MCS.\n") + n1 = n1mcs + n2 = n2mcs #-------------------------------------------------------------------------------# #-------------------------------------------------------------------------------# # also try the same procedure by inverting the ordering of mol1 and mol2 # ########################################### ########### mcs ########################### if bSwap==True: - print "\n********************************************************************************************************************************" - print "To ensure that the mapping is symmetric, i.e. mol1->mol2=mol2->mol1, we repeat the same procedure by swapping the molecule order.\n" - print "********************************************************************************************************************************" + print("\n********************************************************************************************************************************") + print("To ensure that the mapping is symmetric, i.e. mol1->mol2=mol2->mol1, we repeat the same procedure by swapping the molecule order.\n") + print("********************************************************************************************************************************") bMCSfailed = False n1mcs = [] n2mcs = [] if(bMCS==True): - print "Running MCS:" - if(bRingsOnly==True): - n2mcs,n1mcs = mcs(mol2,mol1,molForMcs2,molForMcs1,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],bRingsOnly,d,bChiral,sigmaHoleID2,sigmaHoleID1,timeout) - else: - print "\nTrying to run an MCS using all atoms: modified molecules, match elements..." + print("Running MCS:") + if(bRingsOnly==True): + n2mcs,n1mcs = mcs(mol2,mol1,molForMcs2,molForMcs1,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],bRingsOnly,d,bChiral,sigmaHoleID2,sigmaHoleID1,timeout) + else: + print("\nTrying to run an MCS using all atoms: modified molecules, match elements...") n2A,n1A = mcs(mol2,mol1,molForMcs2,molForMcs1,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],False,d,bChiral,sigmaHoleID2,sigmaHoleID1,timeout,bElements=True, bCarbonize=True) - print "Size of mapping: ",len(n1A) + print("Size of mapping: ",len(n1A)) n1mcs = n1A n2mcs = n2A - print "\nTrying to run an MCS using all atoms: unmodified molecules, match elements..." + print("\nTrying to run an MCS using all atoms: unmodified molecules, match elements...") n2B,n1B = mcs(mol2,mol1,molForMcs2,molForMcs1,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],False,d,bChiral,sigmaHoleID2,sigmaHoleID1,timeout,bElements=True, bCarbonize=False) - print "Size of mapping: ",len(n1B) + print("Size of mapping: ",len(n1B)) n1mcs,n2mcs = compare_mappings_by_size( mol1,mol2, n1mcs, n2mcs, n1B, n2B ) # print "\nTrying to run an MCS using all atoms: unmodified molecules, match any atom..." @@ -2179,71 +2179,71 @@ def main(argv): # print "Size of mapping: ",len(n1C) # n1mcs,n2mcs = compare_mappings_by_size( mol1,mol2, n1mcs, n2mcs, n1C, n2C ) - print "Using variant with the mapping size of ",len(n1mcs) + print("Using variant with the mapping size of ",len(n1mcs)) if( bYesRings==True ): n2B,n1B = mcs(mol2,mol1,molForMcs2,molForMcs1,bH2H,bH2Hpolar,bH2heavy,cmdl['-dMCS'],True,d,bChiral,sigmaHoleID2,sigmaHoleID1,timeout) - n1mcs,n2mcs = compare_mappings_by_size( mol1,mol2, n1mcs, n2mcs, n1B, n2B ) - print "Using final MCS mapping of size ",len(n1mcs) + n1mcs,n2mcs = compare_mappings_by_size( mol1,mol2, n1mcs, n2mcs, n1B, n2B ) + print("Using final MCS mapping of size ",len(n1mcs)) if len(n1mcs)==0: - bMCSfailed = True + bMCSfailed = True ######################################## ####### alignment ###################### n1align = [] n2align = [] if( (bAlignment==True) or (bMCSfailed==True) ): - print "\nRunning alignment:" + print("\nRunning alignment:") if(bRingsOnly==True): n2align,n1align,pyO3A = o3a_alignment(mol2,mol1,bH2H,bH2Hpolar,bH2heavy,bRingsOnly,sigmaHoleID2,sigmaHoleID1,True,d) else: n2align,n1align,pyO3A = o3a_alignment(mol2,mol1,bH2H,bH2Hpolar,bH2heavy,False,sigmaHoleID2,sigmaHoleID1,True,d) - print "Size of mapping: ",len(n1align) + print("Size of mapping: ",len(n1align)) if( bYesRings==True ): mol1 = cp.deepcopy(molcp1) mol2 = cp.deepcopy(molcp2) n2B,n1B,pyO3A = o3a_alignment(mol2,mol1,bH2H,bH2Hpolar,bH2heavy,True,sigmaHoleID2,sigmaHoleID1,True,d) - print "Size of mapping: ",len(n1B) + print("Size of mapping: ",len(n1B)) if(len(n1align)<=len(n1B)): n1align = n1B n2align = n2B # select the better result (mcs or align) and compare with the non-inverted mapping if (len(n1align)<=len(n1)) and (len(n1mcs)<=len(n1)): - print "Swapping of the molecules did not yield a better atom mapping." + print("Swapping of the molecules did not yield a better atom mapping.") if (len(n1align)>=len(n1mcs)) and (len(n1align)>len(n1)): - print "The final result is based on the O3A alignment after swapping the molecule order (mol2-mol1).\n" + print("The final result is based on the O3A alignment after swapping the molecule order (mol2-mol1).\n") n1 = n1align n2 = n2align elif (len(n1align)len(n1)): - print "The final result is based on the MCS after swapping the molecule order (mol2-mol1).\n" + print("The final result is based on the MCS after swapping the molecule order (mol2-mol1).\n") n1 = n1mcs n2 = n2mcs - print "\n" + print("\n") #*******************************************************************************# #*******************************************************************************# #*******************************************************************************# # a check if( len(n1) != len(n2) ): - print "Warning: something went wrong." - print "Number of the morphable atoms in the ligands does not match.\n" - + print("Warning: something went wrong.") + print("Number of the morphable atoms in the ligands does not match.\n") + # calculate score score = calcScore(mol1,mol2,n1,n2,bH2H,bH2heavy) # print some output - print "FINAL RESULTS" + print("FINAL RESULTS") if( bH2H==True or bH2heavy==True ): - print "Atoms considered in mol1: ",mol1.GetNumAtoms() - print "Atoms considered in mol2: ",mol2.GetNumAtoms() + print("Atoms considered in mol1: ",mol1.GetNumAtoms()) + print("Atoms considered in mol2: ",mol2.GetNumAtoms()) else: - print "Atoms considered in mol1: ",mol1.GetNumHeavyAtoms() - print "Atoms considered in mol2: ",mol2.GetNumHeavyAtoms() - print "Morphable atoms in both molecules: ",len(n1),len(n2) - print "Dissimilarity (distance) score: %.4f\n" % score + print("Atoms considered in mol1: ",mol1.GetNumHeavyAtoms()) + print("Atoms considered in mol2: ",mol2.GetNumHeavyAtoms()) + print("Morphable atoms in both molecules: ",len(n1),len(n2)) + print("Dissimilarity (distance) score: %.4f\n" % score) if(cmdl['-score']): - fp = open(cmdl['-score'],'w') - fp.write("Score: %.4f\n" % score) - fp.close() + fp = open(cmdl['-score'],'w') + fp.write("Score: %.4f\n" % score) + fp.close() restoreAtomNames(mol1,atomNameID1) restoreAtomNames(mol2,atomNameID2) @@ -2253,15 +2253,15 @@ def main(argv): # Chem.rdMolAlign.AlignMol(mol1,molcp1,atomMap=zip(n1,n1)) Chem.MolToPDBFile(molcp1,cmdl['-opdb1']) if cmdl.opt['-opdb2'].is_set: -# if( cmdl['-mcs']==True ): +# if( cmdl['-mcs']==True ): try: # Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(n2,n1)) - Chem.rdMolAlign.AlignMol(mol2,molcp1,atomMap=zip(n2,n1)) + Chem.rdMolAlign.AlignMol(mol2,molcp1,atomMap=list(zip(n2,n1))) except: - print "Cannot superimpose -opdb2 structure. Maybe no morphable atoms have been found\n" + print("Cannot superimpose -opdb2 structure. Maybe no morphable atoms have been found\n") Chem.MolToPDBFile(mol2,cmdl['-opdb2']) if cmdl.opt['-opdbm1'].is_set: - mol = subMolByIndex(molcp1,n1) + mol = subMolByIndex(molcp1,n1) Chem.MolToPDBFile(mol,cmdl['-opdbm1']) if cmdl.opt['-opdbm2'].is_set: mol = subMolByIndex(mol2,n2) @@ -2274,5 +2274,3 @@ def main(argv): write_pairs(n2,n1,pairsFile) main( sys.argv ) - - diff --git a/pmx/scripts/ligands/build_mst_graph.py b/pmx/scripts/ligands/build_mst_graph.py index 8ea85657..d72fa485 100755 --- a/pmx/scripts/ligands/build_mst_graph.py +++ b/pmx/scripts/ligands/build_mst_graph.py @@ -16,17 +16,17 @@ ################################################################### class graphOptions: def __init__(self, nodeDeg, bMST=True, filename=None): - self.opt = {} + self.opt = {} - ### by default, MST graph options ### - self.opt['dpi'] = 300 + ### by default, MST graph options ### + self.opt['dpi'] = 300 self.opt['layout'] = "spring" # spring, random, shell, spectral, circular, fruchterman_reingold # node options self.opt['nodeSizeScale'] = 100 self.opt['nodeSizeSlope'] = 0.2 # scaling for the node size self.opt['nodeShape'] = "o" # s o ^ > v < d p h 8 self.opt['nodeColor'] = nodeDeg # nodeDeg, b: blue, g: green, r: red, c: cyan, m: magenta, y: yellow, k: black, w: white - self.opt['nodeCMAP'] = "hot" # http://wiki.scipy.org/Cookbook/Matplotlib/Show_colormaps + self.opt['nodeCMAP'] = "hot" # http://wiki.scipy.org/Cookbook/Matplotlib/Show_colormaps self.opt['nodeVmin'] = 0.1 # self.opt['nodeVmax'] = 1.5 # self.opt['nodeTransparency'] = 1.0 @@ -37,7 +37,7 @@ def __init__(self, nodeDeg, bMST=True, filename=None): self.opt['nodeFontSize'] = 3 self.opt['nodeFontFamily'] = 'sans-serif' self.opt['nodeFontWeight'] = 'bold' # http://matplotlib.org/api/font_manager_api.html - self.opt['nodeLabelOffsetX'] = 0.0 + self.opt['nodeLabelOffsetX'] = 0.0 self.opt['nodeLabelOffsetY'] = 0.0 # edge options self.opt['edgeWidth'] = 0.1 @@ -57,43 +57,43 @@ def __init__(self, nodeDeg, bMST=True, filename=None): self.opt['edgeLabelPos'] = 0.5 # 0=head, 0.5=center, 1=tail) self.opt['edgeLabelTransp']= 1.0 - ### default for the RefLig - if bMST==False: + ### default for the RefLig + if bMST==False: self.opt['layout'] = "circular" # spring, random, shell, spectral, circular, fruchterman_reingold - ### read from file - if filename is not None: - self.read_from_file(filename,nodeDeg) + ### read from file + if filename is not None: + self.read_from_file(filename,nodeDeg) self.opt['nodeVmin'] = min(nodeDeg)*self.opt['nodeVmin'] # self.opt['nodeVmax'] = max(nodeDeg)*self.opt['nodeVmax'] # def read_from_file(self,filename,nodeDeg): - fp = open(filename,'r') - lines = fp.readlines() - fp.close() - lines = pmxparser.kickOutComments( lines, comment = '#') - for l in lines: - l = l.rstrip() - l = l.lstrip() - foo = l.split() - foo[-1] = foo[-1].replace("'","") - foo[-1] = foo[-1].replace("\"","") - if 'None' == foo[-1]: - self.opt[foo[0]] = None - continue - if 'False' == foo[-1]: - self.opt[foo[0]] = None - continue - if 'True' == foo[-1]: - self.opt[foo[0]] = True - continue - self.opt[foo[0]] = foo[-1] - if ('Size' in foo[0]) or ('min' in foo[0]) or ('max' in foo[0]) or ('Transp' in foo[0]) or ('Width' in foo[0]) or ('Pos' in foo[0]) or ('Offset' in foo[0]): - self.opt[foo[0]] = float(foo[-1]) - # some options need adjustment - if self.opt['nodeColor']=='var': - self.opt['nodeColor']=nodeDeg + fp = open(filename,'r') + lines = fp.readlines() + fp.close() + lines = pmxparser.kickOutComments( lines, comment = '#') + for l in lines: + l = l.rstrip() + l = l.lstrip() + foo = l.split() + foo[-1] = foo[-1].replace("'","") + foo[-1] = foo[-1].replace("\"","") + if 'None' == foo[-1]: + self.opt[foo[0]] = None + continue + if 'False' == foo[-1]: + self.opt[foo[0]] = None + continue + if 'True' == foo[-1]: + self.opt[foo[0]] = True + continue + self.opt[foo[0]] = foo[-1] + if ('Size' in foo[0]) or ('min' in foo[0]) or ('max' in foo[0]) or ('Transp' in foo[0]) or ('Width' in foo[0]) or ('Pos' in foo[0]) or ('Offset' in foo[0]): + self.opt[foo[0]] = float(foo[-1]) + # some options need adjustment + if self.opt['nodeColor']=='var': + self.opt['nodeColor']=nodeDeg ################################################################### ################################################################### ################################################################### @@ -108,16 +108,16 @@ def plotImages(cmdl,layout,G,nsize,nodeNames,ligImg): for n in G.nodes(): namePNG = namePathFromPNG(ligImg) - nodeName = nodeNames[n] + nodeName = nodeNames[n] imgFilename = namePNG+"/"+nodeName+".png" - if os.path.isfile(imgFilename)==False: - print "Image not found: ",imgFilename + if os.path.isfile(imgFilename)==False: + print("Image not found: ",imgFilename) continue # img=mpimg.imread('/home/vgapsys/project/make_hybrid/thrombin_test_set/o3a_mapping/foo/lig_2ZC9.png') - img=mpimg.imread(imgFilename) + img=mpimg.imread(imgFilename) G.node[n]['image'] = img - imsize = const_imsize*nsize[n] - imsize = 0.1 + imsize = const_imsize*nsize[n] + imsize = 0.1 xx,yy=trans(layout[n]) # figure (graph) coordinates xa,ya=trans2((xx,yy)) # axes coordinates a = plt.axes([xa-imsize/2.0,ya-imsize/2.0,imsize,imsize]) @@ -131,43 +131,43 @@ def edgesRefLig(refLig,nodeNames,mat,cycle): edges = [] # first edges are special if cycle==0: - for i in xrange(0,shape(mat)[0]): - if nodeNames[i]==refLig: - for j in xrange(0,shape(mat)[1]): - if i==j: - continue - newEdge = [i,j] - edges.append(newEdge) - mat[i,j] = np.inf - mat[j,i] = np.inf - break + for i in range(0,shape(mat)[0]): + if nodeNames[i]==refLig: + for j in range(0,shape(mat)[1]): + if i==j: + continue + newEdge = [i,j] + edges.append(newEdge) + mat[i,j] = np.inf + mat[j,i] = np.inf + break # other edges are different: constructing cycles else: - for i in xrange(0,shape(mat)[0]): + for i in range(0,shape(mat)[0]): if nodeNames[i]==refLig: - continue - else: - j = np.argsort(mat[i])[0,1] - newEdge = [i,j] - edges.append(newEdge) - mat[i,j] = np.inf - mat[j,i] = np.inf + continue + else: + j = np.argsort(mat[i])[0,1] + newEdge = [i,j] + edges.append(newEdge) + mat[i,j] = np.inf + mat[j,i] = np.inf return(edges) -def identifyRefLig(mat,cmdlopt,nodeNames): +def identifyRefLig(mat,cmdlopt,nodeNames): refName = '' if cmdlopt.is_set: - refName = cmdlopt.value - if refName not in nodeNames: - print "The name provided for the reference ligand is not found among the molecules: ",refName - sys.exit(1) + refName = cmdlopt.value + if refName not in nodeNames: + print("The name provided for the reference ligand is not found among the molecules: ",refName) + sys.exit(1) else: - minRowSum = 999.99 - for i in range(0,shape(mat)[0]): - rowSum = np.sum(mat[i]) - if rowSum < minRowSum: - minRowSum = rowSum - refName = nodeNames[i] + minRowSum = 999.99 + for i in range(0,shape(mat)[0]): + rowSum = np.sum(mat[i]) + if rowSum < minRowSum: + minRowSum = rowSum + refName = nodeNames[i] return(refName) def plotMol(pdb,filename): @@ -208,18 +208,18 @@ def writeFormatPDB(fname,m,title="",nr=1): # chlorine if( 'CL' in atom.name or 'Cl' in atom.name or 'cl' in atom.name ): foo.name = "CL"+" " - print >>fp, foo + print(foo, file=fp) # bromine elif( 'BR' in atom.name or 'Br' in atom.name or 'br' in atom.name ): foo.name = "BR"+" " - print >>fp, foo + print(foo, file=fp) elif( len(atom.name) > 4): # too long atom name foo = cp.deepcopy(atom) foo.name = foo.name[:4] - print >>fp, foo + print(foo, file=fp) else: - print >>fp, atom - print >>fp, 'ENDMDL' + print(atom, file=fp) + print('ENDMDL', file=fp) fp.close() def reformatPDB(filename,num): @@ -229,10 +229,10 @@ def reformatPDB(filename,num): rem = [] for a in m.atoms: if 'EP' in a.name: - rem.append(a) + rem.append(a) # remove for a in rem: - m.remove_atom(a) + m.remove_atom(a) writeFormatPDB(newname,m) return(newname) @@ -241,10 +241,10 @@ def findInPythonpath(filename): pythonpath = os.environ.get('PYTHONPATH') foo = pythonpath.split(":") for folder in foo: - script = folder+"/"+filename - if(os.path.isfile(script)==True): - path = script - break + script = folder+"/"+filename + if(os.path.isfile(script)==True): + path = script + break return(path) def getNodeNames(mat,fileName=None): @@ -252,21 +252,21 @@ def getNodeNames(mat,fileName=None): nodeNum = len(mat) # node names are simply numbers if(fileName==None): - count = 0 - for n in xrange(0,nodeNum): - nodeNames.append(count) - count = count + 1 + count = 0 + for n in range(0,nodeNum): + nodeNames.append(count) + count = count + 1 # node names are read from a file else: with open(fileName) as fp: for line in fp: line = line.rstrip() - nodeNames.append(line.split()[0]) - fp.close() + nodeNames.append(line.split()[0]) + fp.close() return(nodeNames) def getNodeDegrees(nodeNames,edgeList): - nodeConn = [0 for n in xrange(0,len(nodeNames))] + nodeConn = [0 for n in range(0,len(nodeNames))] for edge in edgeList: nodeConn[edge[0]] = nodeConn[edge[0]] + 1 nodeConn[edge[1]] = nodeConn[edge[1]] + 1 @@ -275,15 +275,15 @@ def getNodeDegrees(nodeNames,edgeList): def writeNodes(fileName,nodeNames,nodeDeg): fp = open(fileName,"w") for n,conn in zip(nodeNames,nodeDeg): - fp.write("%s %s\n" % (n,conn)) + fp.write("%s %s\n" % (n,conn)) fp.close() def writeEdges(filename,nodeNames,edgeList,mat): fp = open(filename,"w") for edge in edgeList: - n1 = nodeNames[edge[0]] - n2 = nodeNames[edge[1]] - fp.write("%s cr %s %s\n" % (n1,n2,mat[edge[0],edge[1]])) + n1 = nodeNames[edge[0]] + n2 = nodeNames[edge[1]] + fp.write("%s cr %s %s\n" % (n1,n2,mat[edge[0],edge[1]])) fp.close() def modifyMat(edges,mat): @@ -296,7 +296,7 @@ def modifyMat(edges,mat): def genGraph(mat,edgeList,nx): G=nx.Graph() - nodes = range(0,mat.shape[0]) + nodes = list(range(0,mat.shape[0])) G.add_nodes_from(nodes) edgesG = [] for edges in edgeList: @@ -307,7 +307,7 @@ def genGraph(mat,edgeList,nx): def genNodeLabels(mat,nodeNames,layout,opt): labels = {} - nodes = range(0,mat.shape[0]) + nodes = list(range(0,mat.shape[0])) i = 0 for node,name in zip(nodes,nodeNames): labels[i] = name @@ -315,9 +315,9 @@ def genNodeLabels(mat,nodeNames,layout,opt): # adjust label positions outlayout = cp.deepcopy(layout) - for key in layout.keys(): - outlayout[key][0] += opt['nodeLabelOffsetX'] - outlayout[key][1] += opt['nodeLabelOffsetY'] + for key in list(layout.keys()): + outlayout[key][0] += opt['nodeLabelOffsetX'] + outlayout[key][1] += opt['nodeLabelOffsetY'] return(labels,outlayout) @@ -334,13 +334,13 @@ def genEdgeLabels(G): def mstPrim(matRMSD): mat = matRMSD.copy() vertexNum = mat.shape[0] - spanningEdges = [] + spanningEdges = [] vertexVisited = [0] visitedNum = 1 diagInd = np.arange(vertexNum) mat[diagInd, diagInd] = np.inf while visitedNum != vertexNum: - newEdge = np.argmin(mat[vertexVisited], axis=None) + newEdge = np.argmin(mat[vertexVisited], axis=None) newEdge = divmod(newEdge, vertexNum) newEdge = [vertexVisited[newEdge[0]], newEdge[1]] spanningEdges.append(newEdge) @@ -361,7 +361,7 @@ def readMat(fileName): dim = len(foo) if(rowNum == 0): mat = initMat(dim) - for i in xrange(0,dim): + for i in range(0,dim): mat[rowNum][i] = float(foo[i]) rowNum = rowNum + 1 #print(line) @@ -369,12 +369,12 @@ def readMat(fileName): return(mat) def initMat(dim): - mat = [[0 for x in xrange(dim)] for x in xrange(dim)] + mat = [[0 for x in range(dim)] for x in range(dim)] return(mat) def symMat(mat,row): - for i in xrange(0,row): - mat[row][i] = mat[i][row] + for i in range(0,row): + mat[row][i] = mat[i][row] mat[row][row] = 0 return(mat) @@ -398,36 +398,36 @@ def doMorphes(pdbs,callString,outMatFile,ligImg=None): for pdb1 in pdbs: if(ligImg!=None): - namePDB = nameFromPDB(pdb1) - namePNG = namePathFromPNG(ligImg) + namePDB = nameFromPDB(pdb1) + namePNG = namePathFromPNG(ligImg) imgFilename = namePNG+"/"+namePDB+".png" - # check if png exists - if os.path.isfile(imgFilename)==False: - plotMolTransparent(pdb1,imgFilename) - #sys.exit(0) - rmsdMat = symMat(rmsdMat,rowCount) - visited.append(pdb1) - colCount = rowCount + 1 - nodeNames.append( nameFromPDB(pdb1) ) - for pdb2 in pdbs: - if pdb2 in visited: - continue - callS = callString+" -i1 "+pdb1+" -i2 "+pdb2+" -score "+outMatFile - print callS - os.system(callS) - fp = open(outMatFile,"r") - foo = fp.read().rstrip() - rmsdMat[rowCount][colCount] = float(foo.split(" ")[-1]) - fp.close() - colCount = colCount + 1 - rowCount = rowCount + 1 + # check if png exists + if os.path.isfile(imgFilename)==False: + plotMolTransparent(pdb1,imgFilename) + #sys.exit(0) + rmsdMat = symMat(rmsdMat,rowCount) + visited.append(pdb1) + colCount = rowCount + 1 + nodeNames.append( nameFromPDB(pdb1) ) + for pdb2 in pdbs: + if pdb2 in visited: + continue + callS = callString+" -i1 "+pdb1+" -i2 "+pdb2+" -score "+outMatFile + print(callS) + os.system(callS) + fp = open(outMatFile,"r") + foo = fp.read().rstrip() + rmsdMat[rowCount][colCount] = float(foo.split(" ")[-1]) + fp.close() + colCount = colCount + 1 + rowCount = rowCount + 1 fp = open(outMatFile,"w") for row in rmsdMat: - l = '' - for col in row: - l = l+" "+str(col) - fp.write("%s\n" % l) + l = '' + for col in row: + l = l+" "+str(col) + fp.write("%s\n" % l) fp.close() return(rmsdMat,nodeNames) @@ -435,10 +435,10 @@ def doMorphes(pdbs,callString,outMatFile,ligImg=None): def main(argv): desc=('Build a Minimum Spanning Tree or a Tree based on a reference ligand suggesting the alchemical pairs of ligands to morphe.', - '', - '-ligImg: provide a path to the ligand images. The script will search for /path/NodeName.png files.', - 'If -ligImg path has no images (as .png files), the images will be created from the .pdb files (if -pdb is provided).', - ) + '', + '-ligImg: provide a path to the ligand images. The script will search for /path/NodeName.png files.', + 'If -ligImg path has no images (as .png files), the images will be created from the .pdb files (if -pdb is provided).', + ) # define input/output files @@ -467,13 +467,13 @@ def main(argv): Cartesian coordinate space to define the morphes"), Option( "-d", "float", "0.05", "distance (nm) between atoms to consider them morphable"), Option( "-cycleNum", "int", "0", "number of cycles to build"), - Option( "-timeout", "float", "60.0", "maximum time (s) for an MCS search"), + Option( "-timeout", "float", "60.0", "maximum time (s) for an MCS search"), ] help_text = ("Build a Minimum Spanning Tree suggesting the alchemical pairs of ligands to morphe.", - "Provide an RMSD matrix of distances between ligands, a path to the ligand pdbs or a path to the distance scores.", - "If the pdbs are provided, the atoms_to_morph.py will be called to generate an RMSD matrix." - ) + "Provide an RMSD matrix of distances between ligands, a path to the ligand pdbs or a path to the distance scores.", + "If the pdbs are provided, the atoms_to_morph.py will be called to generate an RMSD matrix." + ) cmdl = Commandline( argv, options = options, fileoptions = files, program_desc = help_text, check_for_existing_files = False, version = "0.0" ) @@ -482,27 +482,27 @@ def main(argv): cycleNum = 0 ligImg = None if cmdl.opt['-ormsd'].is_set: - outMatFile = cmdl['-ormsd'] + outMatFile = cmdl['-ormsd'] if cmdl.opt['-cycleNum'].is_set: - cycleNum = cmdl['-cycleNum'] + cycleNum = cmdl['-cycleNum'] if cmdl.opt['-ligImg'].is_set: ligImg = cmdl['-ligImg'] bMST = True if cmdl.opt['-mst'].is_set: - bMST = cmdl.opt['-mst'].value + bMST = cmdl.opt['-mst'].value # pdb_list or rmsd_mat if( cmdl.opt['-pdb'].is_set==True ): - print "Calculate dissimilarities between the ligands." -# if( (cmdl.opt['-alignment'].is_set==False) and (cmdl.opt['-mcs'].is_set==False) ): -# print "For ligand mapping need to select -alignment or -mcs" -# sys.exit(1) - if( len(findInPythonpath("atoms_to_morph.py"))==0 ): - print "Place atoms_to_morph.py in the PYTHONPATH" - sys.exit(1) - callString = "python "+findInPythonpath("atoms_to_morph.py") + print("Calculate dissimilarities between the ligands.") +# if( (cmdl.opt['-alignment'].is_set==False) and (cmdl.opt['-mcs'].is_set==False) ): +# print "For ligand mapping need to select -alignment or -mcs" +# sys.exit(1) + if( len(findInPythonpath("atoms_to_morph.py"))==0 ): + print("Place atoms_to_morph.py in the PYTHONPATH") + sys.exit(1) + callString = "python "+findInPythonpath("atoms_to_morph.py") if cmdl.opt['-alignment'].is_set: - callString = callString+" -alignment" + callString = callString+" -alignment" if cmdl.opt['-mcs'].is_set: callString = callString+" -mcs" if cmdl.opt['-H2H'].is_set: @@ -515,16 +515,16 @@ def main(argv): callString = callString+" -timeout "+str(cmdl['-timeout']) if cmdl.opt['-d'].is_set: callString = callString+" -d "+str(cmdl['-d']) - rmsdMat,nodeNames = doMorphes(cmdl['-pdb'],callString,outMatFile,ligImg) + rmsdMat,nodeNames = doMorphes(cmdl['-pdb'],callString,outMatFile,ligImg) elif( cmdl.opt['-rmsd'].is_set==True ): rmsdMat = readMat(cmdl['-rmsd']) - if( cmdl.opt['-iNodes'].is_set==True ): - nodeNames = getNodeNames(rmsdMat,cmdl['-iNodes']) - else: - nodeNames = getNodeNames(rmsdMat) + if( cmdl.opt['-iNodes'].is_set==True ): + nodeNames = getNodeNames(rmsdMat,cmdl['-iNodes']) + else: + nodeNames = getNodeNames(rmsdMat) else: - print "Need to provide either an RMSD matrix or a set of ligand pdbs." - sys.exit(0) + print("Need to provide either an RMSD matrix or a set of ligand pdbs.") + sys.exit(0) # mst or one reference ligand rmsdMat = np.matrix(rmsdMat) @@ -534,24 +534,24 @@ def main(argv): edgeListMain = [] edgeListExtra = [] if bMST: # mst - for mst in xrange(0,cycleNum+1): + for mst in range(0,cycleNum+1): edges = mstPrim(mat) - mat = modifyMat(edges,mat) + mat = modifyMat(edges,mat) edgeList.extend(edges) - if mst==0: - edgeListMain.extend(edges) - else: - edgeListExtra.extend(edges) + if mst==0: + edgeListMain.extend(edges) + else: + edgeListExtra.extend(edges) else: # reference - refLig = identifyRefLig(mat,cmdl.opt['-refName'],nodeNames) - for cycle in xrange(0,cycleNum+1): - edges = edgesRefLig(refLig,nodeNames,mat,cycle) - edgeList.extend(edges) - if cycle==0: - edgeListMain.extend(edges) - else: - edgeListExtra.extend(edges) - print "Using reference ligand: ",refLig + refLig = identifyRefLig(mat,cmdl.opt['-refName'],nodeNames) + for cycle in range(0,cycleNum+1): + edges = edgesRefLig(refLig,nodeNames,mat,cycle) + edgeList.extend(edges) + if cycle==0: + edgeListMain.extend(edges) + else: + edgeListExtra.extend(edges) + print("Using reference ligand: ",refLig) # output nodes nodeDeg = getNodeDegrees(nodeNames,edgeList) @@ -564,64 +564,62 @@ def main(argv): if( cmdl.opt['-graph'].is_set ): import networkx as nx - fnameGraphOpt = None - if cmdl.opt['-graphOpt'].is_set: - fnameGraphOpt = cmdl['-graphOpt'] - - G = genGraph(rmsdMat,edgeList,nx) - GO = graphOptions(nodeDeg,bMST=bMST,filename=fnameGraphOpt) - # graph layout - if( GO.opt['layout'] == "spring" ): - layout=nx.spring_layout(G,weight='weight') - elif( GO.opt['layout'] == "random" ): - layout=nx.random_layout(G) - elif( GO.opt['layout'] == "shell" ): - layout=nx.shell_layout(G) - elif( GO.opt['layout'] == "spectral" ): - layout=nx.spectral_layout(G,weight='weight') - elif( GO.opt['layout'] == "circular" ): - layout=nx.circular_layout(G) - elif( GO.opt['layout'] == "fruchterman_reingold" ): - layout=nx.fruchterman_reingold_layout(G) - - # node size + fnameGraphOpt = None + if cmdl.opt['-graphOpt'].is_set: + fnameGraphOpt = cmdl['-graphOpt'] + + G = genGraph(rmsdMat,edgeList,nx) + GO = graphOptions(nodeDeg,bMST=bMST,filename=fnameGraphOpt) + # graph layout + if( GO.opt['layout'] == "spring" ): + layout=nx.spring_layout(G,weight='weight') + elif( GO.opt['layout'] == "random" ): + layout=nx.random_layout(G) + elif( GO.opt['layout'] == "shell" ): + layout=nx.shell_layout(G) + elif( GO.opt['layout'] == "spectral" ): + layout=nx.spectral_layout(G,weight='weight') + elif( GO.opt['layout'] == "circular" ): + layout=nx.circular_layout(G) + elif( GO.opt['layout'] == "fruchterman_reingold" ): + layout=nx.fruchterman_reingold_layout(G) + + # node size nsize = [ ( ( (i-min(nodeDeg))*GO.opt['nodeSizeSlope']+min(nodeDeg) ) ) * GO.opt['nodeSizeScale'] for i in nodeDeg] - # draw nodes + # draw nodes if(cmdl.opt['-ligImg'].is_set==False): - nx.draw_networkx_nodes(G,pos=layout,node_size=nsize,node_color=GO.opt['nodeColor'],alpha=GO.opt['nodeTransparency'], vmin=GO.opt['nodeVmin'], vmax=GO.opt['nodeVmax'], cmap=GO.opt['nodeCMAP'], linewidths=GO.opt['nodeLineWidth'],node_shape=GO.opt['nodeShape']) - - # node labels - if( (GO.opt['nodeLabels'] != None) and (GO.opt['nodeLabels'] != False) ): - nodeLabels,nodeLabelLayout=genNodeLabels(rmsdMat,nodeNames,layout,GO.opt) - nx.draw_networkx_labels(G,pos=nodeLabelLayout,labels=nodeLabels,font_color=GO.opt['nodeFontColor'],font_weight=GO.opt['nodeFontWeight'],font_size=GO.opt['nodeFontSize'],font_family=GO.opt['nodeFontFamily']) - - # draw edges - if (GO.opt['edgeColorExtra']!=None) and (GO.opt['edgeColorExtra']!=False) and (GO.opt['edgeColorExtra']!=GO.opt['edgeColor']): - G1 = genGraph(rmsdMat,edgeListMain,nx) - nx.draw_networkx_edges(G1,pos=layout,width=GO.opt['edgeWidth'],edge_color=GO.opt['edgeColor'],style=GO.opt['edgeStyle'],alpha=GO.opt['edgeTransparency'],edge_cmap=GO.opt['edgeCMAP'],edge_vmin=GO.opt['edgeVmin'],edge_vmax=GO.opt['edgeVmax']) - # extra edges - if cycleNum>0: + nx.draw_networkx_nodes(G,pos=layout,node_size=nsize,node_color=GO.opt['nodeColor'],alpha=GO.opt['nodeTransparency'], vmin=GO.opt['nodeVmin'], vmax=GO.opt['nodeVmax'], cmap=GO.opt['nodeCMAP'], linewidths=GO.opt['nodeLineWidth'],node_shape=GO.opt['nodeShape']) + + # node labels + if( (GO.opt['nodeLabels'] != None) and (GO.opt['nodeLabels'] != False) ): + nodeLabels,nodeLabelLayout=genNodeLabels(rmsdMat,nodeNames,layout,GO.opt) + nx.draw_networkx_labels(G,pos=nodeLabelLayout,labels=nodeLabels,font_color=GO.opt['nodeFontColor'],font_weight=GO.opt['nodeFontWeight'],font_size=GO.opt['nodeFontSize'],font_family=GO.opt['nodeFontFamily']) + + # draw edges + if (GO.opt['edgeColorExtra']!=None) and (GO.opt['edgeColorExtra']!=False) and (GO.opt['edgeColorExtra']!=GO.opt['edgeColor']): + G1 = genGraph(rmsdMat,edgeListMain,nx) + nx.draw_networkx_edges(G1,pos=layout,width=GO.opt['edgeWidth'],edge_color=GO.opt['edgeColor'],style=GO.opt['edgeStyle'],alpha=GO.opt['edgeTransparency'],edge_cmap=GO.opt['edgeCMAP'],edge_vmin=GO.opt['edgeVmin'],edge_vmax=GO.opt['edgeVmax']) + # extra edges + if cycleNum>0: G2 = genGraph(rmsdMat,edgeListExtra,nx) nx.draw_networkx_edges(G2,pos=layout,width=GO.opt['edgeWidth'],edge_color=GO.opt['edgeColorExtra'],style=GO.opt['edgeStyle'],alpha=GO.opt['edgeTransparency'],edge_cmap=GO.opt['edgeCMAP'],edge_vmin=GO.opt['edgeVmin'],edge_vmax=GO.opt['edgeVmax']) - else: - # draw edges - nx.draw_networkx_edges(G,pos=layout,width=GO.opt['edgeWidth'],edge_color=GO.opt['edgeColor'],style=GO.opt['edgeStyle'],alpha=GO.opt['edgeTransparency'],edge_cmap=GO.opt['edgeCMAP'],edge_vmin=GO.opt['edgeVmin'],edge_vmax=GO.opt['edgeVmax']) + else: + # draw edges + nx.draw_networkx_edges(G,pos=layout,width=GO.opt['edgeWidth'],edge_color=GO.opt['edgeColor'],style=GO.opt['edgeStyle'],alpha=GO.opt['edgeTransparency'],edge_cmap=GO.opt['edgeCMAP'],edge_vmin=GO.opt['edgeVmin'],edge_vmax=GO.opt['edgeVmax']) - # edge lables + # edge lables if( (GO.opt['edgeLabels'] != None) and (GO.opt['edgeLabels'] != False) ): edgeLabels=genEdgeLabels(G) nx.draw_networkx_edge_labels(G,pos=layout,edge_labels=edgeLabels,font_color=GO.opt['edgeFontColor'],font_size=GO.opt['edgeFontSize'],font_family=GO.opt['edgeFontFamily'],font_weight=GO.opt['edgeFontWeight'],label_pos=GO.opt['edgeLabelPos'],alpha=GO.opt['edgeLabelTransp']) - ### if needed, plot images ### - if(cmdl.opt['-ligImg'].is_set==True): -# nodeLabels,nodeLabelLayout=genNodeLabels(rmsdMat,nodeNames,layout,GO.opt) - plotImages(cmdl,layout,G,nsize,nodeNames,ligImg) + ### if needed, plot images ### + if(cmdl.opt['-ligImg'].is_set==True): +# nodeLabels,nodeLabelLayout=genNodeLabels(rmsdMat,nodeNames,layout,GO.opt) + plotImages(cmdl,layout,G,nsize,nodeNames,ligImg) # nx.draw_networkx_labels(G,pos=nodeLabelLayout,labels=nodeLabels,font_color=GO.opt['nodeFontColor'],font_weight=GO.opt['nodeFontWeight'],font_size=GO.opt['nodeFontSize'],font_family=GO.opt['nodeFontFamily']) - plt.axis('off') - plt.savefig(cmdl['-graph'],dpi=GO.opt['dpi'],transparent=True) + plt.axis('off') + plt.savefig(cmdl['-graph'],dpi=GO.opt['dpi'],transparent=True) main( sys.argv ) - - diff --git a/pmx/scripts/ligands/make_hybrid.py b/pmx/scripts/ligands/make_hybrid.py index 8101bd9d..c4d30e35 100755 --- a/pmx/scripts/ligands/make_hybrid.py +++ b/pmx/scripts/ligands/make_hybrid.py @@ -35,12 +35,12 @@ def check_if_exclusion_valid( exclusions, ex ): for excl in exclusions: if excl[0]==ex[0]: # some interactions for this atom are already excluded if len(excl)!=len(ex): # the exclusion lists are of different length - print('ERROR: Something wrong with exclusions: ',excl,ex) + print(('ERROR: Something wrong with exclusions: ',excl,ex)) sys.exit(1) else: for e in excl[1:]: if e not in ex: - print('ERROR: Something wrong with exclusions: ',excl,ex) + print(('ERROR: Something wrong with exclusions: ',excl,ex)) sys.exit(1) return(True) @@ -75,18 +75,18 @@ def sum_charge_of_states( itp ): def findIDinList(ind,decoupAngles): for i in decoupAngles: - if( i==ind ): - return True + if( i==ind ): + return True return False def adjustCoords(m,mol): conf = mol.GetConformer() for ai in m.atoms: - ind = ai.id -# print ai.x[0] - posj = conf.GetAtomPosition(ind-1) - ai.x[0] = posj.x - ai.x[1] = posj.y + ind = ai.id +# print ai.x[0] + posj = conf.GetAtomPosition(ind-1) + ai.x[0] = posj.x + ai.x[1] = posj.y ai.x[2] = posj.z def reformatPDB(filename,num,bStrict=False): @@ -112,7 +112,7 @@ def reformatPDB(filename,num,bStrict=False): def restoreAtomNames(mol,atomNameDict): for atom in mol.GetAtoms(): newname = atom.GetMonomerInfo().GetName() - if newname in atomNameDict.keys(): + if newname in list(atomNameDict.keys()): oldname = atomNameDict[newname] atom.GetMonomerInfo().SetName(oldname) @@ -126,25 +126,25 @@ def writeFormatPDB(fname,m,title="",nr=1,bStrict=False): # chlorine if( 'CL' in atom.name or 'Cl' in atom.name or 'cl' in atom.name ): foo.name = "CL"+" " - print >>fp, foo + print(foo, file=fp) # bromine elif( 'BR' in atom.name or 'Br' in atom.name or 'br' in atom.name ): foo.name = "BR"+" " - print >>fp, foo + print(foo, file=fp) elif( len(atom.name) > atNameLen): # too long atom name foo = xcopy.deepcopy(atom) foo.name = foo.name[:atNameLen] - print >>fp, foo + print(foo, file=fp) else: - print >>fp, atom - print >>fp, 'ENDMDL' + print(atom, file=fp) + print('ENDMDL', file=fp) fp.close() def do_log(fp, s): l = "make_hybrid__log_> "+s - print >>sys.stderr, l - print >>fp, l + print(l, file=sys.stderr) + print(l, file=fp) def make_pairs(m1, m2, m3, m4, bFit, bDist, dd, plist = None, grps = None): @@ -153,15 +153,15 @@ def make_pairs(m1, m2, m3, m4, bFit, bDist, dd, plist = None, grps = None): if plist: for n1, n2 in plist: a1 = m1.fetch_atoms(n1,how='byid')[0] - #print a1 + #print a1 a2 = m2.fetch_atoms(n2,how='byid')[0] pairs.append( (a1, a2)) for atom3 in m3.atoms: if a1.id == atom3.id: atom3.x = a2.x - if(bFit==True): - a4 = m4.fetch_atoms(n2,how='byid')[0] - atom3.x = a4.x + if(bFit==True): + a4 = m4.fetch_atoms(n2,how='byid')[0] + atom3.x = a4.x return pairs if(grps and bDist): lst1 = m1.get_by_id(grps[0]) @@ -180,7 +180,7 @@ def make_pairs(m1, m2, m3, m4, bFit, bDist, dd, plist = None, grps = None): if atom.id == atom3.id: atom3.x = keep.x return pairs - + if(bDist): for atom in m1.atoms: mi = dd # nm @@ -219,102 +219,102 @@ def gen_dih_entry2(a1,a2,a3,a4,dihtype,entry=None,entryB=None,scDumA=1.0,scDumB= entryB = entryB[0].split() entryB = [float(foo) for foo in entryB] if (dihtype == 3 ): - zeroesA = [0,0,0,0,0,0] - zeroesB = [0,0,0,0,0,0] + zeroesA = [0,0,0,0,0,0] + zeroesB = [0,0,0,0,0,0] elif (dihtype == 2): # improper has no multiplicity - angleA = 0 + angleA = 0 angleB = 0 if( entry != None ): angleA = entry[0] if( entryB != None ): angleB = entryB[0] - zeroesA = [angleA,0] - zeroesB = [angleB,0] + zeroesA = [angleA,0] + zeroesB = [angleB,0] else: # all the other types are the same - multA = 0 - multB = 0 - angleA = 0 - angleB = 0 - if( entry != None ): - angleA = entry[0] - multA = entry[2] - if( entryB != None ): - angleB = entryB[0] - multB = entryB[2] + multA = 0 + multB = 0 + angleA = 0 + angleB = 0 + if( entry != None ): + angleA = entry[0] + multA = entry[2] + if( entryB != None ): + angleB = entryB[0] + multB = entryB[2] zeroesA = [angleA,0,multA] zeroesB = [angleB,0,multB] if( entry != None ): - if( dihtype == 3 ): - entry = [float(foo)*scDumA for foo in entry] + if( dihtype == 3 ): + entry = [float(foo)*scDumA for foo in entry] else: entry[1] = scDumA*float(entry[1]) - dih = [a1,a2,a3,a4]+[dihtype]+[[dihtype]+entry]+[[dihtype]+zeroesA] + dih = [a1,a2,a3,a4]+[dihtype]+[[dihtype]+entry]+[[dihtype]+zeroesA] dihList.append(dih) if( entryB != None ): if( dihtype == 3 ): - entryB = [float(foo)*scDumB for foo in entryB] + entryB = [float(foo)*scDumB for foo in entryB] else: - entryB[1] = scDumB*float(entryB[1]) + entryB[1] = scDumB*float(entryB[1]) dih = [a1,a2,a3,a4]+[dihtype]+[[dihtype]+zeroesB]+[[dihtype]+entryB] dihList.append(dih) # if( entry==None ): # dih = ids+entryB+zeroesB # dihList.append(dih) # if( entryB==None ): -# dih = ids+zeroesA+entry -# dihList.append(dih) +# dih = ids+zeroesA+entry +# dihList.append(dih) return dihList # for forcefield.py def gen_dih_entry(ids,entry=None,entryB=None,scDumA=1.0,scDumB=1.0): dihList = [] if (ids[4] == 3 ): - zeroesA = [0,0,0,0,0,0] - zeroesB = [0,0,0,0,0,0] + zeroesA = [0,0,0,0,0,0] + zeroesB = [0,0,0,0,0,0] elif (ids[4] == 2): # improper has no multiplicity - angleA = 0 + angleA = 0 angleB = 0 if( entry != None ): angleA = entry[0] if( entryB != None ): angleB = entryB[0] - zeroesA = [angleA,0] - zeroesB = [angleB,0] + zeroesA = [angleA,0] + zeroesB = [angleB,0] else: # all the other types are the same - multA = 0 - multB = 0 - angleA = 0 - angleB = 0 - if( entry != None ): - angleA = entry[0] - multA = entry[2] - if( entryB != None ): - angleB = entryB[0] - multB = entryB[2] + multA = 0 + multB = 0 + angleA = 0 + angleB = 0 + if( entry != None ): + angleA = entry[0] + multA = entry[2] + if( entryB != None ): + angleB = entryB[0] + multB = entryB[2] zeroesA = [angleA,0,multA] zeroesB = [angleB,0,multB] if( entry != None ): - if( ids[4] == 3 ): - entry = [foo*scDumA for foo in entry] + if( ids[4] == 3 ): + entry = [foo*scDumA for foo in entry] else: entry[1] = scDumA*entry[1] - dih = ids+entry+zeroesA + dih = ids+entry+zeroesA dihList.append(dih) if( entryB != None ): if( ids[4] == 3 ): - entryB = [foo*scDumB for foo in entryB] + entryB = [foo*scDumB for foo in entryB] else: - entryB[1] = scDumB*entryB[1] + entryB[1] = scDumB*entryB[1] dih = ids+zeroesB+entryB dihList.append(dih) # if( entry==None ): # dih = ids+entryB+zeroesB # dihList.append(dih) # if( entryB==None ): -# dih = ids+zeroesA+entry -# dihList.append(dih) +# dih = ids+zeroesA+entry +# dihList.append(dih) return dihList # for the newer forcefield2.py @@ -336,24 +336,24 @@ def get_ff2_entry(ids, itp, gmx45=True, what = 'bond'): for b in itp.dihedrals: if (b[0].id == ids[0] and b[1].id == ids[1] and b[2].id == ids[2] and b[3].id == ids[3]) or \ (b[3].id == ids[0] and b[2].id == ids[1] and b[1].id == ids[2] and b[0].id == ids[3]): - if( ids[4] == b[4] ): - itp.dihedrals.remove(b) + if( ids[4] == b[4] ): + itp.dihedrals.remove(b) out = xcopy.deepcopy(b) return out[5:] elif (ids[4] == 9): for b in itp.dihedrals: if (b[0].id == ids[0] and b[1].id == ids[1] and b[2].id == ids[2] and b[3].id == ids[3]) or \ (b[3].id == ids[0] and b[2].id == ids[1] and b[1].id == ids[2] and b[0].id == ids[3]): - if( ids[4] == b[4] ): - itp.dihedrals.remove(b) + if( ids[4] == b[4] ): + itp.dihedrals.remove(b) out = xcopy.deepcopy(b) return out[5:] - elif (ids[4]==1 and gmx45==True): + elif (ids[4]==1 and gmx45==True): for b in itp.dihedrals: if (b[0].id == ids[0] and b[1].id == ids[1] and b[2].id == ids[2] and b[3].id == ids[3]) or \ (b[3].id == ids[0] and b[2].id == ids[1] and b[1].id == ids[2] and b[0].id == ids[3]): - if( ids[4] == b[4] ): - itp.dihedrals.remove(b) + if( ids[4] == b[4] ): + itp.dihedrals.remove(b) out = xcopy.deepcopy(b) return out[5:] elif (ids[4]==2 or ids[4]==4 ): # improper @@ -365,7 +365,7 @@ def get_ff2_entry(ids, itp, gmx45=True, what = 'bond'): sum += 1 break if ( (sum ==4) and (b[4]==2 or b[4]==4) ): - itp.dihedrals.remove(b) + itp.dihedrals.remove(b) out = xcopy.deepcopy(b) return out[5:] elif (ids[4]==1 and gmx45==False ): # improper as proper in version < gmx45 @@ -377,13 +377,13 @@ def get_ff2_entry(ids, itp, gmx45=True, what = 'bond'): sum += 1 break if ( (sum == 4) and (b[4]==1) ): - itp.dihedrals.remove(b) + itp.dihedrals.remove(b) out = xcopy.deepcopy(b) return out[5:] return None # for the older forcefield.py -def get_ff_entry(ids, itp, gmx45=True, what = 'bond'): +def get_ff_entry(ids, itp, gmx45=True, what = 'bond'): if what == 'bond': for b in itp.bonds: if (b[0] == ids[0] and b[1] == ids[1]) or \ @@ -399,22 +399,22 @@ def get_ff_entry(ids, itp, gmx45=True, what = 'bond'): for b in itp.dihedrals: if (b[0] == ids[0] and b[1] == ids[1] and b[2] == ids[2] and b[3] == ids[3]) or \ (b[3] == ids[0] and b[2] == ids[1] and b[1] == ids[2] and b[0] == ids[3]): - if( ids[4] == b[4] ): - itp.dihedrals.remove(b) + if( ids[4] == b[4] ): + itp.dihedrals.remove(b) return b[5:] elif (ids[4] == 9): for b in itp.dihedrals: if (b[0] == ids[0] and b[1] == ids[1] and b[2] == ids[2] and b[3] == ids[3]) or \ (b[3] == ids[0] and b[2] == ids[1] and b[1] == ids[2] and b[0] == ids[3]): - if( ids[4] == b[4] ): - itp.dihedrals.remove(b) + if( ids[4] == b[4] ): + itp.dihedrals.remove(b) return b[5:] - elif (ids[4]==1 and gmx45==True): + elif (ids[4]==1 and gmx45==True): for b in itp.dihedrals: if (b[0] == ids[0] and b[1] == ids[1] and b[2] == ids[2] and b[3] == ids[3]) or \ (b[3] == ids[0] and b[2] == ids[1] and b[1] == ids[2] and b[0] == ids[3]): - if( ids[4] == b[4] ): - itp.dihedrals.remove(b) + if( ids[4] == b[4] ): + itp.dihedrals.remove(b) return b[5:] elif (ids[4]==2 or ids[4]==4 ): # improper for b in itp.dihedrals: @@ -425,7 +425,7 @@ def get_ff_entry(ids, itp, gmx45=True, what = 'bond'): sum += 1 break if ( (sum ==4) and (b[4]==2 or b[4]==4) ): - itp.dihedrals.remove(b) + itp.dihedrals.remove(b) return b[5:] elif (ids[4]==1 and gmx45==False ): # improper as proper in version < gmx45 for b in itp.dihedrals: @@ -436,7 +436,7 @@ def get_ff_entry(ids, itp, gmx45=True, what = 'bond'): sum += 1 break if ( (sum == 4) and (b[4]==1) ): - itp.dihedrals.remove(b) + itp.dihedrals.remove(b) return b[5:] return None @@ -444,7 +444,7 @@ def read_pairs_file(fn): l = open(fn).readlines() plst = [] for line in l: - plst.append(line.split()) + plst.append(line.split()) return plst ################################################################################33 @@ -452,857 +452,857 @@ def read_pairs_file(fn): def main(argv): - version = "1.1" - - # define input/output files - files= [ - FileOption("-l1", "r",["pdb"],"ligand1.pdb",""), - FileOption("-l2", "r",["pdb"],"ligand2.pdb",""), - FileOption("-itp1", "r",["itp"],"lig1.itp",""), - FileOption("-itp2", "r",["itp"],"lig2.itp",""), - FileOption("-n1", "r/o",["ndx"],"scaffold1" ,""), - FileOption("-n2", "r/o",["ndx"],"scaffold2","" ), - FileOption("-pairs", "r/o",["dat"],"pairs" ,""), - FileOption("-oa", "w",["pdb"],"mergedA.pdb" ,""), - FileOption("-ob", "w",["pdb"],"mergedB.pdb" ,""), - FileOption("-oitp", "w",["itp"],"merged.itp","" ), - FileOption("-ffitp", "w",["itp"],"ffmerged.itp" ,""), -# FileOption("-ffitp1", "w/o",["itp"],"ffitp1.itp" ,""), -# FileOption("-ffitp2", "w/o",["itp"],"ffitp2.itp" ,""), - FileOption("-log", "w",["log"],"hybrid.log" ,""), - ] - - # define options - options=[ -# Option( "-bDist", "bool", "False", "use distance (no alignment) for the morphes"), - Option( "-d", "float", "0.05", "distance (nm) between atoms to consider them morphable"), - Option( "-scDUMm", "float", "1.0", "scale dummy masses using the counterpart atoms"), - Option( "-scDUMa", "float", "1.0", "scale bonded dummy angle parameters"), - Option( "-scDUMd", "float", "1.0", "scale bonded dummy dihedral parameters"), - Option( "-deAng", "bool", "false", "decouple angles composed of 1 dummy and 2 non-dummies"), - # Option( "-GMX45", "bool", "true", "set to noGMX45 for the topologies of earlier gromacs generations"), - Option( "-fit", "bool", "false", "fit mol2 onto mol1, only works if pairs.dat is provided"), - Option( "-split", "bool", "false", "split the topology into separate transitions"), - ] - - help_text = () - - # pass options, files and the command line to pymacs - - cmdl = Commandline( argv, options = options, - fileoptions = files, - program_desc = help_text, - check_for_existing_files = False ) - - # deal with flags - if cmdl.opt['-pairs'].is_set: - read_pairs_from_file = True - else: - read_pairs_from_file = False - - gmx45 = True - bFit = False - deAng = False - - bScaleMass = False #inverse of mDUM + version = "1.1" + + # define input/output files + files= [ + FileOption("-l1", "r",["pdb"],"ligand1.pdb",""), + FileOption("-l2", "r",["pdb"],"ligand2.pdb",""), + FileOption("-itp1", "r",["itp"],"lig1.itp",""), + FileOption("-itp2", "r",["itp"],"lig2.itp",""), + FileOption("-n1", "r/o",["ndx"],"scaffold1" ,""), + FileOption("-n2", "r/o",["ndx"],"scaffold2","" ), + FileOption("-pairs", "r/o",["dat"],"pairs" ,""), + FileOption("-oa", "w",["pdb"],"mergedA.pdb" ,""), + FileOption("-ob", "w",["pdb"],"mergedB.pdb" ,""), + FileOption("-oitp", "w",["itp"],"merged.itp","" ), + FileOption("-ffitp", "w",["itp"],"ffmerged.itp" ,""), +# FileOption("-ffitp1", "w/o",["itp"],"ffitp1.itp" ,""), +# FileOption("-ffitp2", "w/o",["itp"],"ffitp2.itp" ,""), + FileOption("-log", "w",["log"],"hybrid.log" ,""), + ] + + # define options + options=[ +# Option( "-bDist", "bool", "False", "use distance (no alignment) for the morphes"), + Option( "-d", "float", "0.05", "distance (nm) between atoms to consider them morphable"), + Option( "-scDUMm", "float", "1.0", "scale dummy masses using the counterpart atoms"), + Option( "-scDUMa", "float", "1.0", "scale bonded dummy angle parameters"), + Option( "-scDUMd", "float", "1.0", "scale bonded dummy dihedral parameters"), + Option( "-deAng", "bool", "false", "decouple angles composed of 1 dummy and 2 non-dummies"), +# Option( "-GMX45", "bool", "true", "set to noGMX45 for the topologies of earlier gromacs generations"), + Option( "-fit", "bool", "false", "fit mol2 onto mol1, only works if pairs.dat is provided"), + Option( "-split", "bool", "false", "split the topology into separate transitions"), + ] + + help_text = () + + # pass options, files and the command line to pymacs + + cmdl = Commandline( argv, options = options, + fileoptions = files, + program_desc = help_text, + check_for_existing_files = False ) + + # deal with flags + if cmdl.opt['-pairs'].is_set: + read_pairs_from_file = True + else: + read_pairs_from_file = False + + gmx45 = True + bFit = False + deAng = False + + bScaleMass = False #inverse of mDUM # if mDUM==True: # bScaleMass = False - if(cmdl['-fit']==True and read_pairs_from_file==True): - bFit = True - if(cmdl['-deAng']==True ): - deAng = True - - if cmdl.opt['-n1'].is_set: - read_from_idx = True - else: - read_from_idx = False - bSplit = cmdl['-split'] - - dist = 0.05 - if( cmdl.opt['-d'].is_set ): - dist = cmdl['-d'] - - scDuma = 1.0 - if( cmdl.opt['-scDUMa'].is_set ): - scDuma = cmdl['-scDUMa'] - scDumd = 1.0 - if( cmdl.opt['-scDUMd'].is_set ): - scDumd = cmdl['-scDUMd'] - scDUMm = 1.0 - if( cmdl.opt['-scDUMm'].is_set ): - scDUMm = cmdl['-scDUMm'] - - logfile = open(cmdl['-log'],'w') - - if read_from_idx and read_pairs_from_file: - do_log(logfile, "Error: Can either read a pair list or scaffold index files!") - do_log(logfile,"Exiting!") - sys.exit(1) - - - do_log(logfile,'Reading ligand 1 from: "%s"' % cmdl['-l1']) - do_log(logfile,'Reading ligand 2 from: "%s"' % cmdl['-l2']) - - m1 = Model().read(cmdl['-l1']) - m2 = Model().read(cmdl['-l2']) - - do_log(logfile,'Reading itp file 1 from: "%s"' % cmdl['-itp1']) - do_log(logfile,'Reading itp file 2 from: "%s"' % cmdl['-itp2']) - - itp1 = ITPFile(cmdl['-itp1']) - itp2 = ITPFile(cmdl['-itp2']) - - do_log(logfile,"Assigning forcefield parameters....") - assign_ff(m1,itp1) - assign_ff(m2,itp2) - do_log(logfile,"Making pairs.....") - - if read_pairs_from_file: - do_log(logfile,'Reading file with atom pairs: "%s"' % cmdl['-pairs']) - plst = read_pairs_file(cmdl['-pairs']) - else: - plst = None - - if read_from_idx: - do_log(logfile,'Reading scaffold index file: "%s"' % cmdl['-n1']) -# grp1 = IndexFile(args['-n1']['fns']).dic['scaffold'] - grp1 = IndexFile(cmdl['-n1']).dic['scaffold'] - do_log(logfile,'Reading scaffold index file: "%s"' % cmdl['-n2']) - grp2 = IndexFile(cmdl['-n2']).dic['scaffold'] - # now we add all atoms with bonds to scaffold atoms - for b in itp1.bonds: - if b[0] in grp1.ids and b[1] not in grp1.ids: - grp1.ids.append(b[1]) - do_log(logfile,'Adding atom %s to scaffold 1' % m1.atoms[b[1]-1].name) - elif b[1] in grp1.ids and b[0] not in grp1.ids: - grp1.ids.append(b[0]) - do_log(logfile,'Adding atom %s to scaffold 1' % m1.atoms[b[0]-1].name) - for b in itp2.bonds: - if b[0] in grp2.ids and b[1] not in grp2.ids: - grp2.ids.append(b[1]) - do_log(logfile,'Adding atom %s to scaffold 2' % m2.atoms[b[1]-1].name) - elif b[1] in grp2.ids and b[0] not in grp2.ids: - grp2.ids.append(b[0]) - do_log(logfile,'Adding atom %s to scaffold 2' % m2.atoms[b[0]-1].name) - grps = [grp1.ids, grp2.ids] - else: - grps = None - - m3 = m1.copy() #m3 will contain all the atoms from m1, but with the coordinates of the matching atoms from m2 - m4 = m2.copy() #need to copy it when fitting - - # fitting - if(bFit==True): - from rdkit import Chem - from rdkit.Chem import AllChem - n1 = [] - n2 = [] - for p in plst: - n1.append(int(p[0])-1) - n2.append(int(p[1])-1) - - do_log(logfile,'Superimposing mol2 on mol1') - try: - pdbName1,atomNameDict1 = reformatPDB(cmdl['-l1'],1) - pdbName2,atomNameDict2 = reformatPDB(cmdl['-l2'],2) - mol1 = Chem.MolFromPDBFile(pdbName1,removeHs=False,sanitize=False) - mol2 = Chem.MolFromPDBFile(pdbName2,removeHs=False,sanitize=False) - os.remove(pdbName1) - os.remove(pdbName2) - Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(n2,n1)) - except: - pdbName1,atomNameDict1 = reformatPDB(cmdl['-l1'],1,bStrict=True) - pdbName2,atomNameDict2 = reformatPDB(cmdl['-l2'],2,bStrict=True) - mol1 = Chem.MolFromPDBFile(pdbName1,removeHs=False,sanitize=False) - mol2 = Chem.MolFromPDBFile(pdbName2,removeHs=False,sanitize=False) - os.remove(pdbName1) - os.remove(pdbName2) - Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=zip(n2,n1)) - # adjust coordinates of m2 - adjustCoords(m2,mol2) - restoreAtomNames(mol1,atomNameDict1) - restoreAtomNames(mol2,atomNameDict2) - - do_log(logfile,'Superimposing mol1 on mol2') - try: - pdbName1,atomNameDict1 = reformatPDB(cmdl['-l1'],1) - pdbName2,atomNameDict2 = reformatPDB(cmdl['-l2'],2) - mol1 = Chem.MolFromPDBFile(pdbName1,removeHs=False,sanitize=False) - mol2 = Chem.MolFromPDBFile(pdbName2,removeHs=False,sanitize=False) - os.remove(pdbName1) - os.remove(pdbName2) - Chem.rdMolAlign.AlignMol(mol1,mol2,atomMap=zip(n1,n2)) - except: - pdbName1,atomNameDict1 = reformatPDB(cmdl['-l1'],1,bStrict=True) - pdbName2,atomNameDict2 = reformatPDB(cmdl['-l2'],2,bStrict=True) - mol1 = Chem.MolFromPDBFile(pdbName1,removeHs=False,sanitize=False) - mol2 = Chem.MolFromPDBFile(pdbName2,removeHs=False,sanitize=False) - os.remove(pdbName1) - os.remove(pdbName2) - Chem.rdMolAlign.AlignMol(mol1,mol2,atomMap=zip(n1,n2)) - # adjust coordinates of m1 - adjustCoords(m3,mol1) - restoreAtomNames(mol1,atomNameDict1) - restoreAtomNames(mol2,atomNameDict2) -# sys.exit(0) - - bDist = True - pairs = make_pairs(m1, m2, m3, m4, bFit, bDist,dist, plst, grps) - - morphsA = map(lambda p: p[1], pairs) - morphsB = map(lambda p: p[0], pairs) - dumsA = [] - dumsA_nofit = [] - if(bFit==False): - for atom in m2.atoms: - if atom not in morphsA: - dumsA.append(atom) - else: - for (atom,at) in zip(m2.atoms,m4.atoms): - if atom not in morphsA: - dumsA.append(atom) - dumsA_nofit.append(at) - dumsB = [] - for atom in m1.atoms: - if atom not in morphsB: - dumsB.append(atom) - do_log(logfile, "Generated %d atom-atom pairs" % len(pairs)) - do_log(logfile,"Dummies in state A: %d" % len(dumsA)) - do_log(logfile,"Dummies in state B: %d" % len(dumsB)) - - - - do_log(logfile,"Making B-states....") - for a1, a2 in pairs: - a1.atomtypeB = a2.atomtype - a2.atomtypeB = a1.atomtype #this is my change to catch the DISAPPEARING dihedrals - a1.nameB = a2.name - a1.qB = a2.q - a1.mB = a2.m - a1.idB = a2.id - a2.idB = a1.id #this is my change to catch the DISAPPEARING dihedrals - a2.mB = a1.m - do_log(logfile, "Atom....: %4d %12s | %6.2f | %6.2f -> %12s | %6.2f | %6.2f" %\ - (a1.id, a1.atomtype, a1.q, a1.m, a1.atomtypeB, a1.qB, a1.mB)) - - if( bFit==False): - for atom in dumsA: - atom.id_old = atom.id - atom.nameB = atom.name - atom.name = 'D'+atom.name - atom.atomtypeB = atom.atomtype - atom.atomtype = 'DUM_'+atom.atomtype - atom.qB = atom.q - atom.q = 0 - atom.mB = atom.m - atom.m = atom.mB #1. - - atom.m = atom.m*scDUMm - if( atom.m < 1.0 and atom.mB != 0.0): # exception for virtual particles - atom.m = 1.0 - - m1.residues[0].append(atom) - m3.residues[0].append(atom) - do_log(logfile, "Dummy...: %4d %12s | %6.2f | %6.2f -> %12s | %6.2f | %6.2f" %\ - (atom.id, atom.atomtype, atom.q, atom.m, atom.atomtypeB, atom.qB, atom.mB)) - else: - for (atom,at) in zip(dumsA,dumsA_nofit): - atom.id_old = atom.id - atom.nameB = atom.name - atom.name = 'D'+atom.name - atom.atomtypeB = atom.atomtype - atom.atomtype = 'DUM_'+atom.atomtype - atom.qB = atom.q - atom.q = 0 - atom.mB = atom.m - atom.m = atom.mB #1. - - atom.m = atom.m*scDUMm - if( atom.m < 1.0 and atom.mB != 0.0): # exception for virtual particles - atom.m = 1.0 - - m1.residues[0].append(atom) - at.id_old = at.id - at.nameB = at.name - at.name = 'D'+at.name - at.atomtypeB = at.atomtype - at.atomtype = 'DUM_'+at.atomtype - at.qB = at.q - at.q = 0 - at.mB = at.m - at.m = at.mB #1. - - at.m = at.m*scDUMm - if( at.m < 1.0 and at.mB != 0.0): # exception for virtual particles - at.m = 1.0 - - m3.residues[0].append(at) - do_log(logfile, "Dummy...: %4d %12s | %6.2f | %6.2f -> %12s | %6.2f | %6.2f" %\ - (atom.id, atom.atomtype, atom.q, atom.m, atom.atomtypeB, atom.qB, atom.mB)) - - - for atom in dumsB: - atom.atomtypeB = 'DUM_'+atom.atomtype - atom.qB = 0 - atom.mB = atom.m #1. - - atom.mB = atom.mB*scDUMm - if( atom.mB < 1.0 and atom.m != 0.0): # exception for virtual particles - atom.mB = 1.0 - - do_log(logfile, "Dummy...: %4d %12s | %6.2f | %6.2f -> %12s | %6.2f | %6.2f" %\ - (atom.id, atom.atomtype, atom.q, atom.m, atom.atomtypeB, atom.qB, atom.mB)) - - id_dicAB = {} - id_dicBA = {} - for atom in m1.atoms: - if hasattr(atom,"idB"): - id_dicAB[atom.id] = atom.idB - id_dicBA[atom.idB] = atom.id - if hasattr(atom,"id_old"): - id_dicAB[atom.id] = atom.id_old - id_dicBA[atom.id_old] = atom.id - - do_log(logfile, "Generating bonded parameters....") - - - # go over bonds - newbonds = [] - - for b in itp1.bonds: - id1 = b[0].id - id2 = b[1].id - a1 = m1.atoms[id1-1] - a2 = m1.atoms[id2-1] - bOk = False - if hasattr(a1,"idB") and hasattr(a2,"idB"): - idB1 = a1.idB - idB2 = a2.idB - entr = get_ff2_entry([idB1, idB2], itp2, gmx45, what= 'bond') - if entr is not None: - newbonds.append ([b[0],b[1],b[2],[b[2]]+b[3],[b[2]]+entr]) - bOk = True - else: - bOk = False - elif a1.atomtypeB[:3] == 'DUM' or a2.atomtypeB[:3] == 'DUM': - entr = get_ff2_entry([a1.id, a2.id], itp1, gmx45, what= 'bond') - if entr is not None: - newbonds.append ([b[0],b[1],b[2],[b[2]]+b[3],[b[2]]+entr]) - bOk = True - else: - bOk = False - else: - newbonds.append(b) - bOk = True - - if not bOk: - do_log(logfile, "Error: Something went wrong while assigning bonds!") - do_log(logfile, "A-> Atom1: %d-%s Atom2: %d-%s" %(a1.id, a1.name, a2.id, a2.name)) - do_log(logfile, "B-> Atom1: %d-%s Atom2: %d-%s" %(a1.idB, a1.nameB, a2.idB, a2.nameB)) - do_log(logfile,"Exiting....") - sys.exit(1) - - # angles - newangles = [] - decoupAngles = [] - for b in itp1.angles: - angtype = b[3] - ####### explanation for angle parameters ############ - # for angtype 1, entry is [angle,force_const] - # for angtype 5, entry is [5,angle,force_const,bond,force_const] - # write_angles() in forcefield2.py expects entry [angtype,angle,force_const,...] - id1 = b[0].id - id2 = b[1].id - id3 = b[2].id - a1 = m1.atoms[id1-1] - a2 = m1.atoms[id2-1] - a3 = m1.atoms[id3-1] - bOk = False - if hasattr(a1,"idB") and hasattr(a2,"idB") and hasattr(a3,"idB"): - idB1 = a1.idB - idB2 = a2.idB - idB3 = a3.idB - entr = get_ff2_entry([idB1, idB2, idB3], itp2, gmx45, what= 'angle') - if entr is not None: - if angtype==1: - newangles.append ([b[0],b[1],b[2],angtype,[angtype]+b[4],[angtype]+entr]) - else: - newangles.append ([b[0],b[1],b[2],angtype,b[4],entr]) - bOk = True - else: - bOk = False - elif a1.atomtypeB[:3] == 'DUM' or \ - a2.atomtypeB[:3] == 'DUM' or \ - a3.atomtypeB[:3] == 'DUM': - entr = get_ff2_entry([a1.id, a2.id, a3.id], itp1, gmx45, what= 'angle') - if (angtype!=1) and (entr is not None): # remove the angtype from the entr - entr = entr[1:] - if entr is not None: - if( (a1.atomtypeB[:3] != 'DUM' and a2.atomtypeB[:3] != 'DUM') \ - or (a1.atomtypeB[:3] != 'DUM' and a3.atomtypeB[:3] != 'DUM') \ - or (a2.atomtypeB[:3] != 'DUM' and a3.atomtypeB[:3] != 'DUM') ): -# if( (a1.atomtypeB[:3] != 'DUM') or (a2.atomtypeB[:3] != 'DUM') or (a3.atomtypeB[:3] != 'DUM') ): - entr[1] = scDuma*entr[1] - if angtype==5: - entr[3] = scDuma*entr[3] - if(deAng==True): - if( a1.atomtypeB[:3] == 'DUM' ): - if( findIDinList(id1,decoupAngles)==True ): - entr[1] = 0.0 - if angtype==5: - entr[3] = 0.0 - else: - decoupAngles.append(id1) - elif( a2.atomtypeB[:3] == 'DUM' ): - if( findIDinList(id2,decoupAngles)==True ): - entr[1] = 0.0 - if angtype==5: - entr[3] = 0.0 - else: - decoupAngles.append(id2) - elif( a3.atomtypeB[:3] == 'DUM' ): - if( findIDinList(id3,decoupAngles)==True ): - entr[1] = 0.0 - if angtype==5: - entr[3] = 0.0 - else: - decoupAngles.append(id3) - if angtype==1: - newangles.append ([b[0],b[1],b[2],angtype,[angtype]+b[4],[angtype]+entr]) - else: - newangles.append ([b[0],b[1],b[2],angtype,b[4],[angtype]+entr]) - bOk = True - else: - bOk = False - else: - newangles.append(b) - bOk = True - - if not bOk: - do_log(logfile, "Error: Something went wrong while assigning angles!") - do_log(logfile, "A-> Atom1: %d-%s Atom2: %d-%s Atom3: %d-%s" \ - %(a1.id, a1.name, a2.id, a2.name, a3.id, a3.name)) - do_log(logfile, "B-> Atom1: %d-%s Atom2: %d-%s Atom3: %d-%s" \ - %(a1.idB, a1.nameB, a2.idB, a2.nameB, a3.idB, a3.nameB)) - do_log(logfile,"Exiting....") - sys.exit(1) - - - ############################# - ############ VG ############# - # COMPLETE DIHEDRAL REWRITE # - ############################# - newdihedrals = [] - cpItp1 = xcopy.deepcopy(itp1) - cpItp2 = xcopy.deepcopy(itp2) - for b in itp1.dihedrals: - id1 = b[0].id - id2 = b[1].id - id3 = b[2].id - id4 = b[3].id - dih_type = b[4] - a1 = m1.atoms[id1-1] - a2 = m1.atoms[id2-1] - a3 = m1.atoms[id3-1] - a4 = m1.atoms[id4-1] - entrA = get_ff2_entry([id1, id2, id3, id4, dih_type], cpItp1, gmx45, what= 'dihedral') - bOk = False - if hasattr(a1,"idB") and hasattr(a2,"idB") and \ - hasattr(a3,"idB") and hasattr(a4,"idB"): - # switch the A state off - dih = gen_dih_entry2(a1, a2, a3, a4, dih_type, entrA,None) - newdihedrals.extend(dih) - bOk = True - else: - # switch the B state on - if a1.atomtypeB[:3] == 'DUM' or \ - a2.atomtypeB[:3] == 'DUM' or \ - a3.atomtypeB[:3] == 'DUM' or \ - a4.atomtypeB[:3] == 'DUM': - if entrA is not None: - dih = gen_dih_entry2(a1, a2, a3, a4, dih_type,entrA,None) - newdihedrals.extend(dih) + if(cmdl['-fit']==True and read_pairs_from_file==True): + bFit = True + if(cmdl['-deAng']==True ): + deAng = True + + if cmdl.opt['-n1'].is_set: + read_from_idx = True + else: + read_from_idx = False + bSplit = cmdl['-split'] + + dist = 0.05 + if( cmdl.opt['-d'].is_set ): + dist = cmdl['-d'] + + scDuma = 1.0 + if( cmdl.opt['-scDUMa'].is_set ): + scDuma = cmdl['-scDUMa'] + scDumd = 1.0 + if( cmdl.opt['-scDUMd'].is_set ): + scDumd = cmdl['-scDUMd'] + scDUMm = 1.0 + if( cmdl.opt['-scDUMm'].is_set ): + scDUMm = cmdl['-scDUMm'] + + logfile = open(cmdl['-log'],'w') + + if read_from_idx and read_pairs_from_file: + do_log(logfile, "Error: Can either read a pair list or scaffold index files!") + do_log(logfile,"Exiting!") + sys.exit(1) + + + do_log(logfile,'Reading ligand 1 from: "%s"' % cmdl['-l1']) + do_log(logfile,'Reading ligand 2 from: "%s"' % cmdl['-l2']) + + m1 = Model().read(cmdl['-l1']) + m2 = Model().read(cmdl['-l2']) + + do_log(logfile,'Reading itp file 1 from: "%s"' % cmdl['-itp1']) + do_log(logfile,'Reading itp file 2 from: "%s"' % cmdl['-itp2']) + + itp1 = ITPFile(cmdl['-itp1']) + itp2 = ITPFile(cmdl['-itp2']) + + do_log(logfile,"Assigning forcefield parameters....") + assign_ff(m1,itp1) + assign_ff(m2,itp2) + do_log(logfile,"Making pairs.....") + + if read_pairs_from_file: + do_log(logfile,'Reading file with atom pairs: "%s"' % cmdl['-pairs']) + plst = read_pairs_file(cmdl['-pairs']) + else: + plst = None + + if read_from_idx: + do_log(logfile,'Reading scaffold index file: "%s"' % cmdl['-n1']) +# grp1 = IndexFile(args['-n1']['fns']).dic['scaffold'] + grp1 = IndexFile(cmdl['-n1']).dic['scaffold'] + do_log(logfile,'Reading scaffold index file: "%s"' % cmdl['-n2']) + grp2 = IndexFile(cmdl['-n2']).dic['scaffold'] + # now we add all atoms with bonds to scaffold atoms + for b in itp1.bonds: + if b[0] in grp1.ids and b[1] not in grp1.ids: + grp1.ids.append(b[1]) + do_log(logfile,'Adding atom %s to scaffold 1' % m1.atoms[b[1]-1].name) + elif b[1] in grp1.ids and b[0] not in grp1.ids: + grp1.ids.append(b[0]) + do_log(logfile,'Adding atom %s to scaffold 1' % m1.atoms[b[0]-1].name) + for b in itp2.bonds: + if b[0] in grp2.ids and b[1] not in grp2.ids: + grp2.ids.append(b[1]) + do_log(logfile,'Adding atom %s to scaffold 2' % m2.atoms[b[1]-1].name) + elif b[1] in grp2.ids and b[0] not in grp2.ids: + grp2.ids.append(b[0]) + do_log(logfile,'Adding atom %s to scaffold 2' % m2.atoms[b[0]-1].name) + grps = [grp1.ids, grp2.ids] + else: + grps = None + + m3 = m1.copy() #m3 will contain all the atoms from m1, but with the coordinates of the matching atoms from m2 + m4 = m2.copy() #need to copy it when fitting + + # fitting + if(bFit==True): + from rdkit import Chem + from rdkit.Chem import AllChem + n1 = [] + n2 = [] + for p in plst: + n1.append(int(p[0])-1) + n2.append(int(p[1])-1) + + do_log(logfile,'Superimposing mol2 on mol1') + try: + pdbName1,atomNameDict1 = reformatPDB(cmdl['-l1'],1) + pdbName2,atomNameDict2 = reformatPDB(cmdl['-l2'],2) + mol1 = Chem.MolFromPDBFile(pdbName1,removeHs=False,sanitize=False) + mol2 = Chem.MolFromPDBFile(pdbName2,removeHs=False,sanitize=False) + os.remove(pdbName1) + os.remove(pdbName2) + Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=list(zip(n2,n1))) + except: + pdbName1,atomNameDict1 = reformatPDB(cmdl['-l1'],1,bStrict=True) + pdbName2,atomNameDict2 = reformatPDB(cmdl['-l2'],2,bStrict=True) + mol1 = Chem.MolFromPDBFile(pdbName1,removeHs=False,sanitize=False) + mol2 = Chem.MolFromPDBFile(pdbName2,removeHs=False,sanitize=False) + os.remove(pdbName1) + os.remove(pdbName2) + Chem.rdMolAlign.AlignMol(mol2,mol1,atomMap=list(zip(n2,n1))) + # adjust coordinates of m2 + adjustCoords(m2,mol2) + restoreAtomNames(mol1,atomNameDict1) + restoreAtomNames(mol2,atomNameDict2) + + do_log(logfile,'Superimposing mol1 on mol2') + try: + pdbName1,atomNameDict1 = reformatPDB(cmdl['-l1'],1) + pdbName2,atomNameDict2 = reformatPDB(cmdl['-l2'],2) + mol1 = Chem.MolFromPDBFile(pdbName1,removeHs=False,sanitize=False) + mol2 = Chem.MolFromPDBFile(pdbName2,removeHs=False,sanitize=False) + os.remove(pdbName1) + os.remove(pdbName2) + Chem.rdMolAlign.AlignMol(mol1,mol2,atomMap=list(zip(n1,n2))) + except: + pdbName1,atomNameDict1 = reformatPDB(cmdl['-l1'],1,bStrict=True) + pdbName2,atomNameDict2 = reformatPDB(cmdl['-l2'],2,bStrict=True) + mol1 = Chem.MolFromPDBFile(pdbName1,removeHs=False,sanitize=False) + mol2 = Chem.MolFromPDBFile(pdbName2,removeHs=False,sanitize=False) + os.remove(pdbName1) + os.remove(pdbName2) + Chem.rdMolAlign.AlignMol(mol1,mol2,atomMap=list(zip(n1,n2))) + # adjust coordinates of m1 + adjustCoords(m3,mol1) + restoreAtomNames(mol1,atomNameDict1) + restoreAtomNames(mol2,atomNameDict2) +# sys.exit(0) + + bDist = True + pairs = make_pairs(m1, m2, m3, m4, bFit, bDist,dist, plst, grps) + + morphsA = [p[1] for p in pairs] + morphsB = [p[0] for p in pairs] + dumsA = [] + dumsA_nofit = [] + if(bFit==False): + for atom in m2.atoms: + if atom not in morphsA: + dumsA.append(atom) + else: + for (atom,at) in zip(m2.atoms,m4.atoms): + if atom not in morphsA: + dumsA.append(atom) + dumsA_nofit.append(at) + dumsB = [] + for atom in m1.atoms: + if atom not in morphsB: + dumsB.append(atom) + do_log(logfile, "Generated %d atom-atom pairs" % len(pairs)) + do_log(logfile,"Dummies in state A: %d" % len(dumsA)) + do_log(logfile,"Dummies in state B: %d" % len(dumsB)) + + + + do_log(logfile,"Making B-states....") + for a1, a2 in pairs: + a1.atomtypeB = a2.atomtype + a2.atomtypeB = a1.atomtype #this is my change to catch the DISAPPEARING dihedrals + a1.nameB = a2.name + a1.qB = a2.q + a1.mB = a2.m + a1.idB = a2.id + a2.idB = a1.id #this is my change to catch the DISAPPEARING dihedrals + a2.mB = a1.m + do_log(logfile, "Atom....: %4d %12s | %6.2f | %6.2f -> %12s | %6.2f | %6.2f" %\ + (a1.id, a1.atomtype, a1.q, a1.m, a1.atomtypeB, a1.qB, a1.mB)) + + if( bFit==False): + for atom in dumsA: + atom.id_old = atom.id + atom.nameB = atom.name + atom.name = 'D'+atom.name + atom.atomtypeB = atom.atomtype + atom.atomtype = 'DUM_'+atom.atomtype + atom.qB = atom.q + atom.q = 0 + atom.mB = atom.m + atom.m = atom.mB #1. + + atom.m = atom.m*scDUMm + if( atom.m < 1.0 and atom.mB != 0.0): # exception for virtual particles + atom.m = 1.0 + + m1.residues[0].append(atom) + m3.residues[0].append(atom) + do_log(logfile, "Dummy...: %4d %12s | %6.2f | %6.2f -> %12s | %6.2f | %6.2f" %\ + (atom.id, atom.atomtype, atom.q, atom.m, atom.atomtypeB, atom.qB, atom.mB)) + else: + for (atom,at) in zip(dumsA,dumsA_nofit): + atom.id_old = atom.id + atom.nameB = atom.name + atom.name = 'D'+atom.name + atom.atomtypeB = atom.atomtype + atom.atomtype = 'DUM_'+atom.atomtype + atom.qB = atom.q + atom.q = 0 + atom.mB = atom.m + atom.m = atom.mB #1. + + atom.m = atom.m*scDUMm + if( atom.m < 1.0 and atom.mB != 0.0): # exception for virtual particles + atom.m = 1.0 + + m1.residues[0].append(atom) + at.id_old = at.id + at.nameB = at.name + at.name = 'D'+at.name + at.atomtypeB = at.atomtype + at.atomtype = 'DUM_'+at.atomtype + at.qB = at.q + at.q = 0 + at.mB = at.m + at.m = at.mB #1. + + at.m = at.m*scDUMm + if( at.m < 1.0 and at.mB != 0.0): # exception for virtual particles + at.m = 1.0 + + m3.residues[0].append(at) + do_log(logfile, "Dummy...: %4d %12s | %6.2f | %6.2f -> %12s | %6.2f | %6.2f" %\ + (atom.id, atom.atomtype, atom.q, atom.m, atom.atomtypeB, atom.qB, atom.mB)) + + + for atom in dumsB: + atom.atomtypeB = 'DUM_'+atom.atomtype + atom.qB = 0 + atom.mB = atom.m #1. + + atom.mB = atom.mB*scDUMm + if( atom.mB < 1.0 and atom.m != 0.0): # exception for virtual particles + atom.mB = 1.0 + + do_log(logfile, "Dummy...: %4d %12s | %6.2f | %6.2f -> %12s | %6.2f | %6.2f" %\ + (atom.id, atom.atomtype, atom.q, atom.m, atom.atomtypeB, atom.qB, atom.mB)) + + id_dicAB = {} + id_dicBA = {} + for atom in m1.atoms: + if hasattr(atom,"idB"): + id_dicAB[atom.id] = atom.idB + id_dicBA[atom.idB] = atom.id + if hasattr(atom,"id_old"): + id_dicAB[atom.id] = atom.id_old + id_dicBA[atom.id_old] = atom.id + + do_log(logfile, "Generating bonded parameters....") + + + # go over bonds + newbonds = [] + + for b in itp1.bonds: + id1 = b[0].id + id2 = b[1].id + a1 = m1.atoms[id1-1] + a2 = m1.atoms[id2-1] + bOk = False + if hasattr(a1,"idB") and hasattr(a2,"idB"): + idB1 = a1.idB + idB2 = a2.idB + entr = get_ff2_entry([idB1, idB2], itp2, gmx45, what= 'bond') + if entr is not None: + newbonds.append ([b[0],b[1],b[2],[b[2]]+b[3],[b[2]]+entr]) + bOk = True + else: + bOk = False + elif a1.atomtypeB[:3] == 'DUM' or a2.atomtypeB[:3] == 'DUM': + entr = get_ff2_entry([a1.id, a2.id], itp1, gmx45, what= 'bond') + if entr is not None: + newbonds.append ([b[0],b[1],b[2],[b[2]]+b[3],[b[2]]+entr]) + bOk = True + else: + bOk = False + else: + newbonds.append(b) + bOk = True + + if not bOk: + do_log(logfile, "Error: Something went wrong while assigning bonds!") + do_log(logfile, "A-> Atom1: %d-%s Atom2: %d-%s" %(a1.id, a1.name, a2.id, a2.name)) + do_log(logfile, "B-> Atom1: %d-%s Atom2: %d-%s" %(a1.idB, a1.nameB, a2.idB, a2.nameB)) + do_log(logfile,"Exiting....") + sys.exit(1) + + # angles + newangles = [] + decoupAngles = [] + for b in itp1.angles: + angtype = b[3] + ####### explanation for angle parameters ############ + # for angtype 1, entry is [angle,force_const] + # for angtype 5, entry is [5,angle,force_const,bond,force_const] + # write_angles() in forcefield2.py expects entry [angtype,angle,force_const,...] + id1 = b[0].id + id2 = b[1].id + id3 = b[2].id + a1 = m1.atoms[id1-1] + a2 = m1.atoms[id2-1] + a3 = m1.atoms[id3-1] + bOk = False + if hasattr(a1,"idB") and hasattr(a2,"idB") and hasattr(a3,"idB"): + idB1 = a1.idB + idB2 = a2.idB + idB3 = a3.idB + entr = get_ff2_entry([idB1, idB2, idB3], itp2, gmx45, what= 'angle') + if entr is not None: + if angtype==1: + newangles.append ([b[0],b[1],b[2],angtype,[angtype]+b[4],[angtype]+entr]) + else: + newangles.append ([b[0],b[1],b[2],angtype,b[4],entr]) + bOk = True + else: + bOk = False + elif a1.atomtypeB[:3] == 'DUM' or \ + a2.atomtypeB[:3] == 'DUM' or \ + a3.atomtypeB[:3] == 'DUM': + entr = get_ff2_entry([a1.id, a2.id, a3.id], itp1, gmx45, what= 'angle') + if (angtype!=1) and (entr is not None): # remove the angtype from the entr + entr = entr[1:] + if entr is not None: + if( (a1.atomtypeB[:3] != 'DUM' and a2.atomtypeB[:3] != 'DUM') \ + or (a1.atomtypeB[:3] != 'DUM' and a3.atomtypeB[:3] != 'DUM') \ + or (a2.atomtypeB[:3] != 'DUM' and a3.atomtypeB[:3] != 'DUM') ): +# if( (a1.atomtypeB[:3] != 'DUM') or (a2.atomtypeB[:3] != 'DUM') or (a3.atomtypeB[:3] != 'DUM') ): + entr[1] = scDuma*entr[1] + if angtype==5: + entr[3] = scDuma*entr[3] + if(deAng==True): + if( a1.atomtypeB[:3] == 'DUM' ): + if( findIDinList(id1,decoupAngles)==True ): + entr[1] = 0.0 + if angtype==5: + entr[3] = 0.0 + else: + decoupAngles.append(id1) + elif( a2.atomtypeB[:3] == 'DUM' ): + if( findIDinList(id2,decoupAngles)==True ): + entr[1] = 0.0 + if angtype==5: + entr[3] = 0.0 + else: + decoupAngles.append(id2) + elif( a3.atomtypeB[:3] == 'DUM' ): + if( findIDinList(id3,decoupAngles)==True ): + entr[1] = 0.0 + if angtype==5: + entr[3] = 0.0 + else: + decoupAngles.append(id3) + if angtype==1: + newangles.append ([b[0],b[1],b[2],angtype,[angtype]+b[4],[angtype]+entr]) + else: + newangles.append ([b[0],b[1],b[2],angtype,b[4],[angtype]+entr]) + bOk = True + else: + bOk = False + else: + newangles.append(b) + bOk = True + + if not bOk: + do_log(logfile, "Error: Something went wrong while assigning angles!") + do_log(logfile, "A-> Atom1: %d-%s Atom2: %d-%s Atom3: %d-%s" \ + %(a1.id, a1.name, a2.id, a2.name, a3.id, a3.name)) + do_log(logfile, "B-> Atom1: %d-%s Atom2: %d-%s Atom3: %d-%s" \ + %(a1.idB, a1.nameB, a2.idB, a2.nameB, a3.idB, a3.nameB)) + do_log(logfile,"Exiting....") + sys.exit(1) + + + ############################# + ############ VG ############# + # COMPLETE DIHEDRAL REWRITE # + ############################# + newdihedrals = [] + cpItp1 = xcopy.deepcopy(itp1) + cpItp2 = xcopy.deepcopy(itp2) + for b in itp1.dihedrals: + id1 = b[0].id + id2 = b[1].id + id3 = b[2].id + id4 = b[3].id + dih_type = b[4] + a1 = m1.atoms[id1-1] + a2 = m1.atoms[id2-1] + a3 = m1.atoms[id3-1] + a4 = m1.atoms[id4-1] + entrA = get_ff2_entry([id1, id2, id3, id4, dih_type], cpItp1, gmx45, what= 'dihedral') + bOk = False + if hasattr(a1,"idB") and hasattr(a2,"idB") and \ + hasattr(a3,"idB") and hasattr(a4,"idB"): + # switch the A state off + dih = gen_dih_entry2(a1, a2, a3, a4, dih_type, entrA,None) + newdihedrals.extend(dih) + bOk = True + else: + # switch the B state on + if a1.atomtypeB[:3] == 'DUM' or \ + a2.atomtypeB[:3] == 'DUM' or \ + a3.atomtypeB[:3] == 'DUM' or \ + a4.atomtypeB[:3] == 'DUM': + if entrA is not None: + dih = gen_dih_entry2(a1, a2, a3, a4, dih_type,entrA,None) + newdihedrals.extend(dih) # if( (a1.atomtypeB[:3] != 'DUM' and a2.atomtypeB[:3] != 'DUM' and a3.atomtypeB[:3] != 'DUM') \ # or (a1.atomtypeB[:3] != 'DUM' and a2.atomtypeB[:3] != 'DUM' and a4.atomtypeB[:3] != 'DUM') \ # or (a2.atomtypeB[:3] != 'DUM' and a3.atomtypeB[:3] != 'DUM' and a4.atomtypeB[:3] != 'DUM') \ # or (a1.atomtypeB[:3] != 'DUM' and a3.atomtypeB[:3] != 'DUM' and a4.atomtypeB[:3] != 'DUM') ): - if( a1.atomtypeB[:3] != 'DUM' or a2.atomtypeB[:3] != 'DUM' or a3.atomtypeB[:3] != 'DUM' or a4.atomtypeB[:3] != 'DUM' ): + if( a1.atomtypeB[:3] != 'DUM' or a2.atomtypeB[:3] != 'DUM' or a3.atomtypeB[:3] != 'DUM' or a4.atomtypeB[:3] != 'DUM' ): # if( (a1.atomtypeB[:3] != 'DUM' and a2.atomtypeB[:3] != 'DUM') \ -# or (a1.atomtypeB[:3] != 'DUM' and a3.atomtypeB[:3] != 'DUM') \ -# or (a1.atomtypeB[:3] != 'DUM' and a4.atomtypeB[:3] != 'DUM') \ -# or (a2.atomtypeB[:3] != 'DUM' and a3.atomtypeB[:3] != 'DUM') \ -# or (a2.atomtypeB[:3] != 'DUM' and a4.atomtypeB[:3] != 'DUM') \ -# or (a3.atomtypeB[:3] != 'DUM' and a4.atomtypeB[:3] != 'DUM') ): - if dih_type==2 or dih_type==4:# or dih_type==1: # disable improper for dummy-nondummy - dih = gen_dih_entry2(a1, a2, a3, a4, dih_type,None,entrA,1.0,0.0) - else: - dih = gen_dih_entry2(a1, a2, a3, a4, dih_type,None,entrA,1.0,scDumd) - else: - dih = gen_dih_entry2(a1, a2, a3, a4, dih_type,None,entrA) - newdihedrals.extend(dih) - bOk = True +# or (a1.atomtypeB[:3] != 'DUM' and a3.atomtypeB[:3] != 'DUM') \ +# or (a1.atomtypeB[:3] != 'DUM' and a4.atomtypeB[:3] != 'DUM') \ +# or (a2.atomtypeB[:3] != 'DUM' and a3.atomtypeB[:3] != 'DUM') \ +# or (a2.atomtypeB[:3] != 'DUM' and a4.atomtypeB[:3] != 'DUM') \ +# or (a3.atomtypeB[:3] != 'DUM' and a4.atomtypeB[:3] != 'DUM') ): + if dih_type==2 or dih_type==4:# or dih_type==1: # disable improper for dummy-nondummy + dih = gen_dih_entry2(a1, a2, a3, a4, dih_type,None,entrA,1.0,0.0) + else: + dih = gen_dih_entry2(a1, a2, a3, a4, dih_type,None,entrA,1.0,scDumd) else: - bOk = False - else: - newdihedrals.append(b) + dih = gen_dih_entry2(a1, a2, a3, a4, dih_type,None,entrA) + newdihedrals.extend(dih) bOk = True - - if not bOk: - do_log(logfile, "Error: Something went wrong while assigning dihedrals!") - do_log(logfile, "A-> Atom1: %d-%s Atom2: %d-%s Atom3: %d-%s Atom3: %d-%s" \ - %(a1.id, a1.name, a2.id, a2.name, a3.id, a3.name, a4.id, a4.name)) - do_log(logfile, "B-> Atom1: %d-%s Atom2: %d-%s Atom3: %d-%s Atom3: %d-%s" \ - %(a1.idB, a1.nameB, a2.idB, a2.nameB, a3.idB, a3.nameB, a4.idB, a4.nameB)) - do_log(logfile,"Exiting....") - sys.exit(1) - - - # second molecule dihedrals - for b in itp2.dihedrals: - id1 = b[0].id - id2 = b[1].id - id3 = b[2].id - id4 = b[3].id - aB1 = m2.atoms[id1-1] - aB2 = m2.atoms[id2-1] - aB3 = m2.atoms[id3-1] - aB4 = m2.atoms[id4-1] - newid1 = id_dicBA[b[0].id] - newid2 = id_dicBA[b[1].id] - newid3 = id_dicBA[b[2].id] - newid4 = id_dicBA[b[3].id] - a1 = m1.atoms[newid1-1] - a2 = m1.atoms[newid2-1] - a3 = m1.atoms[newid3-1] - a4 = m1.atoms[newid4-1] - dih_type = b[4] - entrB = get_ff2_entry([b[0].id,b[1].id,b[2].id,b[3].id, dih_type], cpItp2, gmx45, what='dihedral') - bOk = False - if hasattr(aB1,"idB") and hasattr(aB2,"idB") and \ - hasattr(aB3,"idB") and hasattr(aB4,"idB"): - # switch the B state off - dih = gen_dih_entry2(a1,a2,a3,a4, dih_type,None,entrB) - newdihedrals.extend(dih) - bOk = True + else: + bOk = False else: - # switch the A state on - if a1.atomtype.startswith('DUM') or \ - a2.atomtype.startswith('DUM') or \ - a3.atomtype.startswith('DUM') or \ - a4.atomtype.startswith('DUM'): - if entrB is not None: - dih = gen_dih_entry2(a1,a2,a3,a4,dih_type,None,entrB) - newdihedrals.extend(dih) + newdihedrals.append(b) + bOk = True + + if not bOk: + do_log(logfile, "Error: Something went wrong while assigning dihedrals!") + do_log(logfile, "A-> Atom1: %d-%s Atom2: %d-%s Atom3: %d-%s Atom3: %d-%s" \ + %(a1.id, a1.name, a2.id, a2.name, a3.id, a3.name, a4.id, a4.name)) + do_log(logfile, "B-> Atom1: %d-%s Atom2: %d-%s Atom3: %d-%s Atom3: %d-%s" \ + %(a1.idB, a1.nameB, a2.idB, a2.nameB, a3.idB, a3.nameB, a4.idB, a4.nameB)) + do_log(logfile,"Exiting....") + sys.exit(1) + + + # second molecule dihedrals + for b in itp2.dihedrals: + id1 = b[0].id + id2 = b[1].id + id3 = b[2].id + id4 = b[3].id + aB1 = m2.atoms[id1-1] + aB2 = m2.atoms[id2-1] + aB3 = m2.atoms[id3-1] + aB4 = m2.atoms[id4-1] + newid1 = id_dicBA[b[0].id] + newid2 = id_dicBA[b[1].id] + newid3 = id_dicBA[b[2].id] + newid4 = id_dicBA[b[3].id] + a1 = m1.atoms[newid1-1] + a2 = m1.atoms[newid2-1] + a3 = m1.atoms[newid3-1] + a4 = m1.atoms[newid4-1] + dih_type = b[4] + entrB = get_ff2_entry([b[0].id,b[1].id,b[2].id,b[3].id, dih_type], cpItp2, gmx45, what='dihedral') + bOk = False + if hasattr(aB1,"idB") and hasattr(aB2,"idB") and \ + hasattr(aB3,"idB") and hasattr(aB4,"idB"): + # switch the B state off + dih = gen_dih_entry2(a1,a2,a3,a4, dih_type,None,entrB) + newdihedrals.extend(dih) + bOk = True + else: + # switch the A state on + if a1.atomtype.startswith('DUM') or \ + a2.atomtype.startswith('DUM') or \ + a3.atomtype.startswith('DUM') or \ + a4.atomtype.startswith('DUM'): + if entrB is not None: + dih = gen_dih_entry2(a1,a2,a3,a4,dih_type,None,entrB) + newdihedrals.extend(dih) # if( (a1.atomtype.startswith('DUM')==False and a2.atomtype.startswith('DUM')==False and a3.atomtype.startswith('DUM')==False) \ # or (a1.atomtype.startswith('DUM')==False and a3.atomtype.startswith('DUM')==False and a4.atomtype.startswith('DUM')==False) \ # or (a2.atomtype.startswith('DUM')==False and a3.atomtype.startswith('DUM')==False and a4.atomtype.startswith('DUM')==False) \ # or (a1.atomtype.startswith('DUM')==False and a2.atomtype.startswith('DUM')==False and a4.atomtype.startswith('DUM')==False) ): - if( a1.atomtype.startswith('DUM')==False or a2.atomtype.startswith('DUM')==False \ - or a3.atomtype.startswith('DUM')==False or a4.atomtype.startswith('DUM')==False ): + if( a1.atomtype.startswith('DUM')==False or a2.atomtype.startswith('DUM')==False \ + or a3.atomtype.startswith('DUM')==False or a4.atomtype.startswith('DUM')==False ): # if( (a1.atomtype.startswith('DUM')==False and a2.atomtype.startswith('DUM')==False) \ -# or (a1.atomtype.startswith('DUM')==False and a3.atomtype.startswith('DUM')==False) \ -# or (a1.atomtype.startswith('DUM')==False and a4.atomtype.startswith('DUM')==False) \ -# or (a2.atomtype.startswith('DUM')==False and a3.atomtype.startswith('DUM')==False) \ -# or (a2.atomtype.startswith('DUM')==False and a4.atomtype.startswith('DUM')==False) \ -# or (a3.atomtype.startswith('DUM')==False and a4.atomtype.startswith('DUM')==False) ): - if dih_type==2 or dih_type==4:# or dih_type==1: # disable improper for dummy-nondummy - dih = gen_dih_entry2(a1,a2,a3,a4,dih_type,entrB,None,0.0,1.0) - else: - dih = gen_dih_entry2(a1,a2,a3,a4,dih_type,entrB,None,scDumd,1.0) - else: - dih = gen_dih_entry2(a1,a2,a3,a4,dih_type,entrB,None) - newdihedrals.extend(dih) - bOk = True +# or (a1.atomtype.startswith('DUM')==False and a3.atomtype.startswith('DUM')==False) \ +# or (a1.atomtype.startswith('DUM')==False and a4.atomtype.startswith('DUM')==False) \ +# or (a2.atomtype.startswith('DUM')==False and a3.atomtype.startswith('DUM')==False) \ +# or (a2.atomtype.startswith('DUM')==False and a4.atomtype.startswith('DUM')==False) \ +# or (a3.atomtype.startswith('DUM')==False and a4.atomtype.startswith('DUM')==False) ): + if dih_type==2 or dih_type==4:# or dih_type==1: # disable improper for dummy-nondummy + dih = gen_dih_entry2(a1,a2,a3,a4,dih_type,entrB,None,0.0,1.0) + else: + dih = gen_dih_entry2(a1,a2,a3,a4,dih_type,entrB,None,scDumd,1.0) else: - bOk = False - else: - newdihedrals.append(b) + dih = gen_dih_entry2(a1,a2,a3,a4,dih_type,entrB,None) + newdihedrals.extend(dih) bOk = True - - if not bOk: - do_log(logfile, "Error: Something went wrong while assigning dihedrals!") - do_log(logfile, "A-> Atom1: %d-%s Atom2: %d-%s Atom3: %d-%s Atom3: %d-%s" \ - %(a1.id, a1.name, a2.id, a2.name, a3.id, a3.name, a4.id, a4.name)) - do_log(logfile, "B-> Atom1: %d-%s Atom2: %d-%s Atom3: %d-%s Atom3: %d-%s" \ - %(a1.idB, a1.nameB, a2.idB, a2.nameB, a3.idB, a3.nameB, a4.idB, a4.nameB)) - do_log(logfile,"Exiting....") - sys.exit(1) - ############################# - # COMPLETE DIHEDRAL REWRITE # - ############################# - - - # vsites2: stateA - newvsites2 = [] - has_vsites2 = False + else: + bOk = False + else: + newdihedrals.append(b) + bOk = True + + if not bOk: + do_log(logfile, "Error: Something went wrong while assigning dihedrals!") + do_log(logfile, "A-> Atom1: %d-%s Atom2: %d-%s Atom3: %d-%s Atom3: %d-%s" \ + %(a1.id, a1.name, a2.id, a2.name, a3.id, a3.name, a4.id, a4.name)) + do_log(logfile, "B-> Atom1: %d-%s Atom2: %d-%s Atom3: %d-%s Atom3: %d-%s" \ + %(a1.idB, a1.nameB, a2.idB, a2.nameB, a3.idB, a3.nameB, a4.idB, a4.nameB)) + do_log(logfile,"Exiting....") + sys.exit(1) + ############################# + # COMPLETE DIHEDRAL REWRITE # + ############################# + + + # vsites2: stateA + newvsites2 = [] + has_vsites2 = False # if(itp1.vsites2): # for b in itp1.vsites2: - if(itp1.virtual_sites2): - has_vsites2 = True - for b in itp1.virtual_sites2: - id1 = b[0].id - id2 = b[1].id - id3 = b[2].id - a1 = m1.atoms[id1-1] - a2 = m1.atoms[id2-1] - a3 = m1.atoms[id3-1] - newvsites2.append(b) - - # vsites3: stateA - newvsites3 = [] - has_vsites3 = False - if(itp1.virtual_sites3): - has_vsites3 = True - for b in itp1.virtual_sites3: - id1 = b[0].id - id2 = b[1].id - id3 = b[2].id - id4 = b[3].id - a1 = m1.atoms[id1-1] - a2 = m1.atoms[id2-1] - a3 = m1.atoms[id3-1] - a4 = m1.atoms[id4-1] - newvsites3.append(b) - - # exclusions: stateA - newexclusions = [] - has_exclusions = False - if(itp1.exclusions): - has_exclusions = True - for excl in itp1.exclusions: - exclToAdd = [] - for ex in excl: - newid = ex.id - newa = m1.atoms[newid-1] - exclToAdd.append(newa) - newexclusions.append( exclToAdd ) - - # now we have all parameter for pairs - # let's go for the dummies - for b in itp2.bonds: - newid1 = id_dicBA[b[0].id] - newid2 = id_dicBA[b[1].id] - a1 = m1.atoms[newid1-1] - a2 = m1.atoms[newid2-1] - if a1.atomtype.startswith('DUM') or \ - a2.atomtype.startswith('DUM'): - newbonds.append( [a1, a2, 1, [1]+b[-1], [1]+b[-1]] ) - - decoupAngles = [] - for b in itp2.angles: - angtype = b[3] - entry = b[-1] - # for type 1 - paramA = [ 1,entry[0],0.0 ] - paramAscDum = [ 1,entry[0],scDuma*float(entry[1]) ] - paramB = [ 1,entry[0],entry[1] ] - # for type 5 - if angtype==5: - paramA = [ 5,entry[1],0.0,entry[3],0.0 ] - paramAscDum = [ 5,entry[1],scDuma*float(entry[2]),entry[3],scDuma*float(entry[4]) ] - paramB = [ 5,entry[1],entry[2],entry[3],entry[4] ] - - newid1 = id_dicBA[b[0].id] - newid2 = id_dicBA[b[1].id] - newid3 = id_dicBA[b[2].id] - a1 = m1.atoms[newid1-1] - a2 = m1.atoms[newid2-1] - a3 = m1.atoms[newid3-1] - if a1.atomtype.startswith('DUM') or \ - a2.atomtype.startswith('DUM') or \ - a3.atomtype.startswith('DUM'): - if( (a1.atomtype.startswith('DUM')==False and a2.atomtype.startswith('DUM')==False) \ - or (a1.atomtype.startswith('DUM')==False and a3.atomtype.startswith('DUM')==False) \ - or (a2.atomtype.startswith('DUM')==False and a3.atomtype.startswith('DUM')==False) ): -# if( a1.atomtype.startswith('DUM')==False or a2.atomtype.startswith('DUM')==False or a3.atomtype.startswith('DUM')==False ): - - if(deAng==True): - if( a1.atomtype.startswith('DUM')==True ): - if( findIDinList(newid1,decoupAngles)==True ): - newangles.append([ a1,a2,a3,angtype, paramA, paramB ]) - else: - newangles.append([ a1,a2,a3,angtype, paramAscDum, paramB ]) - decoupAngles.append(newid1) - elif( a2.atomtype.startswith('DUM')==True ): - if( findIDinList(newid2,decoupAngles)==True ): - newangles.append([ a1,a2,a3,angtype, paramA, paramB ]) - else: - newangles.append([ a1,a2,a3,angtype, paramAscDum, paramB ]) - decoupAngles.append(newid2) - elif( a3.atomtype.startswith('DUM')==True ): - if( findIDinList(newid3,decoupAngles)==True ): - newangles.append([ a1,a2,a3,angtype, paramA, paramB ]) - else: - newangles.append([ a1,a2,a3,angtype, paramAscDum, paramB ]) - decoupAngles.append(newid3) - else: - newangles.append([ a1,a2,a3,angtype, paramAscDum, paramB ]) - else: - newangles.append([ a1,a2,a3,angtype, paramB, paramB ]) - - # dihedrals already accounted for both states -# cpcpItp2 = xcopy.deepcopy(cpItp2) # dirty hack -# for b in cpcpItp2.dihedrals: -# newid1 = id_dicBA[b[0]] -# newid2 = id_dicBA[b[1]] -# newid3 = id_dicBA[b[2]] -# newid4 = id_dicBA[b[3]] -# a1 = m1.atoms[newid1-1] -# a2 = m1.atoms[newid2-1] -# a3 = m1.atoms[newid3-1] -# a4 = m1.atoms[newid4-1] -# dih_type = b[4] -# entrB = get_ff_entry([b[0],b[1],b[2],b[3], dih_type], cpItp2, gmx45, what='dihedral') -# if a1.atomtype.startswith('DUM') or \ -# a2.atomtype.startswith('DUM') or \ -# a3.atomtype.startswith('DUM') or \ -# a4.atomtype.startswith('DUM'): -# newdihedrals.append( [newid1, newid2, newid3, newid4, b[4]] + b[5:] + b[5:] ) + if(itp1.virtual_sites2): + has_vsites2 = True + for b in itp1.virtual_sites2: + id1 = b[0].id + id2 = b[1].id + id3 = b[2].id + a1 = m1.atoms[id1-1] + a2 = m1.atoms[id2-1] + a3 = m1.atoms[id3-1] + newvsites2.append(b) + + # vsites3: stateA + newvsites3 = [] + has_vsites3 = False + if(itp1.virtual_sites3): + has_vsites3 = True + for b in itp1.virtual_sites3: + id1 = b[0].id + id2 = b[1].id + id3 = b[2].id + id4 = b[3].id + a1 = m1.atoms[id1-1] + a2 = m1.atoms[id2-1] + a3 = m1.atoms[id3-1] + a4 = m1.atoms[id4-1] + newvsites3.append(b) + + # exclusions: stateA + newexclusions = [] + has_exclusions = False + if(itp1.exclusions): + has_exclusions = True + for excl in itp1.exclusions: + exclToAdd = [] + for ex in excl: + newid = ex.id + newa = m1.atoms[newid-1] + exclToAdd.append(newa) + newexclusions.append( exclToAdd ) + + # now we have all parameter for pairs + # let's go for the dummies + for b in itp2.bonds: + newid1 = id_dicBA[b[0].id] + newid2 = id_dicBA[b[1].id] + a1 = m1.atoms[newid1-1] + a2 = m1.atoms[newid2-1] + if a1.atomtype.startswith('DUM') or \ + a2.atomtype.startswith('DUM'): + newbonds.append( [a1, a2, 1, [1]+b[-1], [1]+b[-1]] ) + + decoupAngles = [] + for b in itp2.angles: + angtype = b[3] + entry = b[-1] + # for type 1 + paramA = [ 1,entry[0],0.0 ] + paramAscDum = [ 1,entry[0],scDuma*float(entry[1]) ] + paramB = [ 1,entry[0],entry[1] ] + # for type 5 + if angtype==5: + paramA = [ 5,entry[1],0.0,entry[3],0.0 ] + paramAscDum = [ 5,entry[1],scDuma*float(entry[2]),entry[3],scDuma*float(entry[4]) ] + paramB = [ 5,entry[1],entry[2],entry[3],entry[4] ] + + newid1 = id_dicBA[b[0].id] + newid2 = id_dicBA[b[1].id] + newid3 = id_dicBA[b[2].id] + a1 = m1.atoms[newid1-1] + a2 = m1.atoms[newid2-1] + a3 = m1.atoms[newid3-1] + if a1.atomtype.startswith('DUM') or \ + a2.atomtype.startswith('DUM') or \ + a3.atomtype.startswith('DUM'): + if( (a1.atomtype.startswith('DUM')==False and a2.atomtype.startswith('DUM')==False) \ + or (a1.atomtype.startswith('DUM')==False and a3.atomtype.startswith('DUM')==False) \ + or (a2.atomtype.startswith('DUM')==False and a3.atomtype.startswith('DUM')==False) ): +# if( a1.atomtype.startswith('DUM')==False or a2.atomtype.startswith('DUM')==False or a3.atomtype.startswith('DUM')==False ): + + if(deAng==True): + if( a1.atomtype.startswith('DUM')==True ): + if( findIDinList(newid1,decoupAngles)==True ): + newangles.append([ a1,a2,a3,angtype, paramA, paramB ]) + else: + newangles.append([ a1,a2,a3,angtype, paramAscDum, paramB ]) + decoupAngles.append(newid1) + elif( a2.atomtype.startswith('DUM')==True ): + if( findIDinList(newid2,decoupAngles)==True ): + newangles.append([ a1,a2,a3,angtype, paramA, paramB ]) + else: + newangles.append([ a1,a2,a3,angtype, paramAscDum, paramB ]) + decoupAngles.append(newid2) + elif( a3.atomtype.startswith('DUM')==True ): + if( findIDinList(newid3,decoupAngles)==True ): + newangles.append([ a1,a2,a3,angtype, paramA, paramB ]) + else: + newangles.append([ a1,a2,a3,angtype, paramAscDum, paramB ]) + decoupAngles.append(newid3) + else: + newangles.append([ a1,a2,a3,angtype, paramAscDum, paramB ]) + else: + newangles.append([ a1,a2,a3,angtype, paramB, paramB ]) + + # dihedrals already accounted for both states +# cpcpItp2 = xcopy.deepcopy(cpItp2) # dirty hack +# for b in cpcpItp2.dihedrals: +# newid1 = id_dicBA[b[0]] +# newid2 = id_dicBA[b[1]] +# newid3 = id_dicBA[b[2]] +# newid4 = id_dicBA[b[3]] +# a1 = m1.atoms[newid1-1] +# a2 = m1.atoms[newid2-1] +# a3 = m1.atoms[newid3-1] +# a4 = m1.atoms[newid4-1] +# dih_type = b[4] +# entrB = get_ff_entry([b[0],b[1],b[2],b[3], dih_type], cpItp2, gmx45, what='dihedral') +# if a1.atomtype.startswith('DUM') or \ +# a2.atomtype.startswith('DUM') or \ +# a3.atomtype.startswith('DUM') or \ +# a4.atomtype.startswith('DUM'): +# newdihedrals.append( [newid1, newid2, newid3, newid4, b[4]] + b[5:] + b[5:] ) # dih = gen_dih_entry([newid1, newid2, newid3, newid4, dih_type],None,entrB) -# newdihedrals.extend(dih) - - # vsites2: stateB - if(itp2.virtual_sites2): - has_vsites2 = True - for b in itp2.virtual_sites2: - newid1 = id_dicBA[b[0].id] - newid2 = id_dicBA[b[1].id] - newid3 = id_dicBA[b[2].id] - #VG: this is not tested, use with caution +# newdihedrals.extend(dih) + + # vsites2: stateB + if(itp2.virtual_sites2): + has_vsites2 = True + for b in itp2.virtual_sites2: + newid1 = id_dicBA[b[0].id] + newid2 = id_dicBA[b[1].id] + newid3 = id_dicBA[b[2].id] + #VG: this is not tested, use with caution # print "UNTESTED PART FOR THE NEW PMX %s %s %s" %(newid1,newid2,newid3) # newid1 = id_dicBA[b[0]] # newid2 = id_dicBA[b[1]] # newid3 = id_dicBA[b[2]] - a1 = m1.atoms[newid1-1] - a2 = m1.atoms[newid2-1] - a3 = m1.atoms[newid3-1] - vsiteToAdd = [a1,a2,a3,b[3],b[4]] - if( check_if_vsite2_exists( newvsites2, vsiteToAdd )==False ): - newvsites2.append( [a1, a2, a3, b[3], b[4]] ) + a1 = m1.atoms[newid1-1] + a2 = m1.atoms[newid2-1] + a3 = m1.atoms[newid3-1] + vsiteToAdd = [a1,a2,a3,b[3],b[4]] + if( check_if_vsite2_exists( newvsites2, vsiteToAdd )==False ): + newvsites2.append( [a1, a2, a3, b[3], b[4]] ) # newvsites2.append( [newid1, newid2, newid3, b[3], b[4]] ) - # vsites3: stateB - if(itp2.virtual_sites3): - has_vsites3 = True - for b in itp2.virtual_sites3: - newid1 = id_dicBA[b[0].id] - newid2 = id_dicBA[b[1].id] - newid3 = id_dicBA[b[2].id] - newid4 = id_dicBA[b[3].id] - a1 = m1.atoms[newid1-1] - a2 = m1.atoms[newid2-1] - a3 = m1.atoms[newid3-1] - a4 = m1.atoms[newid4-1] - vsiteToAdd = [a1,a2,a3,a4,b[4],b[5]] - if( check_if_vsite3_exists( newvsites3, vsiteToAdd )==False ): - newvsites3.append( [a1, a2, a3, a4, b[4], b[5]] ) - - # exclusions: stateB - if(itp2.exclusions): - has_exclusions = True - for excl in itp2.exclusions: - exclToAdd = [] - for ex in excl: - newid = id_dicBA[ex.id] - newa = m1.atoms[newid-1] - exclToAdd.append(newa) - if( check_if_exclusion_valid( newexclusions, exclToAdd )==True ): - newexclusions.append( exclToAdd ) - - # make pairs - newpairs = [] - pp = [] - for p in itp1.pairs: - newpairs.append( p ) - pp.append( (p[0].id,p[1].id) ) - for p in itp2.pairs: - newid1 = id_dicBA[p[0].id] - newid2 = id_dicBA[p[1].id] + # vsites3: stateB + if(itp2.virtual_sites3): + has_vsites3 = True + for b in itp2.virtual_sites3: + newid1 = id_dicBA[b[0].id] + newid2 = id_dicBA[b[1].id] + newid3 = id_dicBA[b[2].id] + newid4 = id_dicBA[b[3].id] a1 = m1.atoms[newid1-1] a2 = m1.atoms[newid2-1] - if (newid1, newid2) not in pp and \ - (newid2, newid1) not in pp: - newpairs.append([ a1, a2, 1] ) - - do_log(logfile, "Generating new itp file") - - newitp = ITPFile(filename=None) - newitp.name = itp1.name - newitp.nrexcl = itp1.nrexcl - newitp.atoms = m1.atoms - newitp.residues = m1.residues - for i, atom in enumerate(newitp.atoms): - atom.cgnr = i +1 - newitp.bonds = newbonds - newitp.pairs = newpairs - newitp.angles = newangles - newitp.dihedrals = newdihedrals - newitp.virtual_sites2 = newvsites2 - newitp.has_vsites2 = has_vsites2 - newitp.virtual_sites3 = newvsites3 - newitp.has_vsites3 = has_vsites3 - newitp.exclusions = newexclusions - newitp.has_exclusions = has_exclusions - # get charges - qA, qB = sum_charge_of_states( newitp ) - qA_mem = xcopy.deepcopy( qA ) - qB_mem = xcopy.deepcopy( qB ) - - do_log(logfile, 'Writing new itp file: "%s"' % cmdl['-oitp']) - newitp.write(cmdl['-oitp'], target_qB = qB) - #do_log(logfile, 'Writing new structure file: "%s"' % args['-o']['fns']) - #m1.write(args['-o']) - do_log(logfile, 'Writing dummy forcefield file: "%s"' % cmdl['-ffitp']) - - if bSplit==True: # write splitted topology - root, ext = os.path.splitext(cmdl['-oitp']) - out_file_qoff = root+'_qoff'+ext - out_file_vdw = root+'_vdw'+ext - out_file_qon = root+'_qon'+ext - - - print '------------------------------------------------------' - print 'log_> Creating splitted topologies............' - print 'log_> Making "qoff" topology : "%s"' % out_file_qoff - contQ = xcopy.deepcopy(qA_mem) - newitp.write( out_file_qoff, stateQ = 'AB', stateTypes = 'AA', dummy_qB='off', - scale_mass = bScaleMass, target_qB = qA, stateBonded = 'AA', full_morphe = False ) - print 'log_> Charge of state A: %g' % newitp.qA - print 'log_> Charge of state B: %g' % newitp.qB - - print '------------------------------------------------------' - print 'log_> Making "vdw" topology : "%s"' % out_file_vdw - contQ = xcopy.deepcopy(qA_mem) - newitp.write( out_file_vdw, stateQ = 'BB', stateTypes = 'AB', dummy_qA='off', dummy_qB = 'off', - scale_mass = bScaleMass, target_qB = contQ, stateBonded = 'AB' , full_morphe = False) - print 'log_> Charge of state A: %g' % newitp.qA - print 'log_> Charge of state B: %g' % newitp.qB - print '------------------------------------------------------' - - print 'log_> Making "qon" topology : "%s"' % out_file_qon - newitp.write( out_file_qon, stateQ = 'BB', stateTypes = 'BB', dummy_qA='off', dummy_qB = 'on', - scale_mass = bScaleMass, target_qB = qB_mem, stateBonded = 'BB' , full_morphe = False) - print 'log_> Charge of state A: %g' % newitp.qA - print 'log_> Charge of state B: %g' % newitp.qB - print '------------------------------------------------------' - - - # write ffitp - fp = open(cmdl['-ffitp'],'w') - dd = [] - print >>fp, '[ atomtypes ]' - for atom in m1.atoms: - if atom.atomtype.startswith('DUM') and atom.atomtype not in dd: - print >>fp, '%8s %12.6f %12.6f %3s %12.6f %12.6f' % \ - (atom.atomtype, 0, 0, 'A',0,0) - dd.append(atom.atomtype) - elif atom.atomtypeB.startswith('DUM') and atom.atomtypeB not in dd: - print >>fp, '%8s %12.6f %12.6f %3s %12.6f %12.6f' % \ - (atom.atomtypeB, 0, 0, 'A',0,0) - dd.append(atom.atomtypeB) - - # write merged pdb - m1.write(cmdl['-oa']) - m3.write(cmdl['-ob']) + a3 = m1.atoms[newid3-1] + a4 = m1.atoms[newid4-1] + vsiteToAdd = [a1,a2,a3,a4,b[4],b[5]] + if( check_if_vsite3_exists( newvsites3, vsiteToAdd )==False ): + newvsites3.append( [a1, a2, a3, a4, b[4], b[5]] ) + + # exclusions: stateB + if(itp2.exclusions): + has_exclusions = True + for excl in itp2.exclusions: + exclToAdd = [] + for ex in excl: + newid = id_dicBA[ex.id] + newa = m1.atoms[newid-1] + exclToAdd.append(newa) + if( check_if_exclusion_valid( newexclusions, exclToAdd )==True ): + newexclusions.append( exclToAdd ) + + # make pairs + newpairs = [] + pp = [] + for p in itp1.pairs: + newpairs.append( p ) + pp.append( (p[0].id,p[1].id) ) + for p in itp2.pairs: + newid1 = id_dicBA[p[0].id] + newid2 = id_dicBA[p[1].id] + a1 = m1.atoms[newid1-1] + a2 = m1.atoms[newid2-1] + if (newid1, newid2) not in pp and \ + (newid2, newid1) not in pp: + newpairs.append([ a1, a2, 1] ) + + do_log(logfile, "Generating new itp file") + + newitp = ITPFile(filename=None) + newitp.name = itp1.name + newitp.nrexcl = itp1.nrexcl + newitp.atoms = m1.atoms + newitp.residues = m1.residues + for i, atom in enumerate(newitp.atoms): + atom.cgnr = i +1 + newitp.bonds = newbonds + newitp.pairs = newpairs + newitp.angles = newangles + newitp.dihedrals = newdihedrals + newitp.virtual_sites2 = newvsites2 + newitp.has_vsites2 = has_vsites2 + newitp.virtual_sites3 = newvsites3 + newitp.has_vsites3 = has_vsites3 + newitp.exclusions = newexclusions + newitp.has_exclusions = has_exclusions + # get charges + qA, qB = sum_charge_of_states( newitp ) + qA_mem = xcopy.deepcopy( qA ) + qB_mem = xcopy.deepcopy( qB ) + + do_log(logfile, 'Writing new itp file: "%s"' % cmdl['-oitp']) + newitp.write(cmdl['-oitp'], target_qB = qB) + #do_log(logfile, 'Writing new structure file: "%s"' % args['-o']['fns']) + #m1.write(args['-o']) + do_log(logfile, 'Writing dummy forcefield file: "%s"' % cmdl['-ffitp']) + + if bSplit==True: # write splitted topology + root, ext = os.path.splitext(cmdl['-oitp']) + out_file_qoff = root+'_qoff'+ext + out_file_vdw = root+'_vdw'+ext + out_file_qon = root+'_qon'+ext + + + print('------------------------------------------------------') + print('log_> Creating splitted topologies............') + print('log_> Making "qoff" topology : "%s"' % out_file_qoff) + contQ = xcopy.deepcopy(qA_mem) + newitp.write( out_file_qoff, stateQ = 'AB', stateTypes = 'AA', dummy_qB='off', + scale_mass = bScaleMass, target_qB = qA, stateBonded = 'AA', full_morphe = False ) + print('log_> Charge of state A: %g' % newitp.qA) + print('log_> Charge of state B: %g' % newitp.qB) + + print('------------------------------------------------------') + print('log_> Making "vdw" topology : "%s"' % out_file_vdw) + contQ = xcopy.deepcopy(qA_mem) + newitp.write( out_file_vdw, stateQ = 'BB', stateTypes = 'AB', dummy_qA='off', dummy_qB = 'off', + scale_mass = bScaleMass, target_qB = contQ, stateBonded = 'AB' , full_morphe = False) + print('log_> Charge of state A: %g' % newitp.qA) + print('log_> Charge of state B: %g' % newitp.qB) + print('------------------------------------------------------') + + print('log_> Making "qon" topology : "%s"' % out_file_qon) + newitp.write( out_file_qon, stateQ = 'BB', stateTypes = 'BB', dummy_qA='off', dummy_qB = 'on', + scale_mass = bScaleMass, target_qB = qB_mem, stateBonded = 'BB' , full_morphe = False) + print('log_> Charge of state A: %g' % newitp.qA) + print('log_> Charge of state B: %g' % newitp.qB) + print('------------------------------------------------------') + + + # write ffitp + fp = open(cmdl['-ffitp'],'w') + dd = [] + print('[ atomtypes ]', file=fp) + for atom in m1.atoms: + if atom.atomtype.startswith('DUM') and atom.atomtype not in dd: + print('%8s %12.6f %12.6f %3s %12.6f %12.6f' % \ + (atom.atomtype, 0, 0, 'A',0,0), file=fp) + dd.append(atom.atomtype) + elif atom.atomtypeB.startswith('DUM') and atom.atomtypeB not in dd: + print('%8s %12.6f %12.6f %3s %12.6f %12.6f' % \ + (atom.atomtypeB, 0, 0, 'A',0,0), file=fp) + dd.append(atom.atomtypeB) + + # write merged pdb + m1.write(cmdl['-oa']) + m3.write(cmdl['-ob']) main( sys.argv ) diff --git a/pmx/scripts/ligands/one_ff_file.py b/pmx/scripts/ligands/one_ff_file.py index f99804b0..13ff554e 100755 --- a/pmx/scripts/ligands/one_ff_file.py +++ b/pmx/scripts/ligands/one_ff_file.py @@ -12,81 +12,80 @@ class FFatom: def __init__(self,list): self.type = list[0] - self.sigmaA = list[1] - self.epsA = list[2] - self.A = list[3] - self.sigmaB = list[4] - self.epsB = list[5] + self.sigmaA = list[1] + self.epsA = list[2] + self.A = list[3] + self.sigmaB = list[4] + self.epsB = list[5] class FFfile: def __init__(self, fname=None): - if fname is not None: - foo = fname.split('.') - bar = re.sub('ff','',foo[0]) - self.name = bar + if fname is not None: + foo = fname.split('.') + bar = re.sub('ff','',foo[0]) + self.name = bar self.atoms = [] - self.read_ffitp(fname) + self.read_ffitp(fname) def read_ffitp(self,file): - l = open(file).readlines() - toSkip = "atomtypes" - for line in l: - if toSkip not in line: - self.atoms.append(FFatom(line.split())) + l = open(file).readlines() + toSkip = "atomtypes" + for line in l: + if toSkip not in line: + self.atoms.append(FFatom(line.split())) def get_atoms( ffs ): atoms = {} for ffile in ffs: ff = FFfile(ffile) for at1 in ff.atoms: - if at1.type in atoms.keys(): # check if atom type already exists + if at1.type in list(atoms.keys()): # check if atom type already exists at2 = atoms[at1.type] - if (at1.type == at2.type and at1.sigmaA == at2.sigmaA and at1.epsA == at2.epsA and at1.sigmaB == at2.sigmaB and at1.epsB == at2.epsB): + if (at1.type == at2.type and at1.sigmaA == at2.sigmaA and at1.epsA == at2.epsA and at1.sigmaB == at2.sigmaB and at1.epsB == at2.epsB): continue else: sys.stdout.write('Found two atoms of type %s, but they have different parameters, consider renaming atom types\n' % at1.type) else: atoms[at1.type] = at1 - + return (atoms) def ffwrite(atoms,file): fp = open(file,'w') - print >>fp, '[ atomtypes ]' - for atype in atoms.keys(): + print('[ atomtypes ]', file=fp) + for atype in list(atoms.keys()): at = atoms[atype] - print >>fp, ' %s %s %s %s %s %s' % (at.type,at.sigmaA,at.epsA,at.A,at.sigmaB,at.epsB) + print(' %s %s %s %s %s %s' % (at.type,at.sigmaA,at.epsA,at.A,at.sigmaB,at.epsB), file=fp) def main(argv): # define input/output files - files= [ - FileOption("-ffitp", "r/m",["itp"],"ffMOL.itp",""), - FileOption("-ffitp_out", "w",["itp"],"ffMOL_out.itp",""), - ] - # define options + files= [ + FileOption("-ffitp", "r/m",["itp"],"ffMOL.itp",""), + FileOption("-ffitp_out", "w",["itp"],"ffMOL_out.itp",""), + ] + # define options - options=[] + options=[] - help_text = () + help_text = () - # pass options, files and the command line to pymacs + # pass options, files and the command line to pymacs - cmdl = Commandline( argv, options = options, - fileoptions = files, - program_desc = help_text, - check_for_existing_files = False ) + cmdl = Commandline( argv, options = options, + fileoptions = files, + program_desc = help_text, + check_for_existing_files = False ) - ffs = cmdl['-ffitp'] + ffs = cmdl['-ffitp'] - #get 2 lists of: 1) equivalent atoms in ffMOL1.itp and ffMOL2.itp 2) different atoms - atoms = get_atoms(ffs) + #get 2 lists of: 1) equivalent atoms in ffMOL1.itp and ffMOL2.itp 2) different atoms + atoms = get_atoms(ffs) - #write new ffMOL.itp - ffwrite(atoms,cmdl['-ffitp_out']) + #write new ffMOL.itp + ffwrite(atoms,cmdl['-ffitp_out']) - sys.stdout.write('All finished correctly\n') + sys.stdout.write('All finished correctly\n') main( sys.argv ) - diff --git a/pmx/scripts/make_amber.py b/pmx/scripts/make_amber.py index edb12831..01ed9f05 100755 --- a/pmx/scripts/make_amber.py +++ b/pmx/scripts/make_amber.py @@ -40,14 +40,14 @@ rna_res = ['RA','RU','RC','RG'] def chain_type(ch): - if ch.residues[0].resname in library._one_letter.keys(): + if ch.residues[0].resname in list(library._one_letter.keys()): return 'pep' elif ch.residues[0].resname in dna_res: return 'dna' elif ch.residues[0].resname in rna_res: return 'rna' else: return 'unk' - + # describe what the script does @@ -68,8 +68,8 @@ def chain_type(ch): files= [ FileOption("-f","r",["pdb"],"protein.pdb","Input pdb file"), FileOption("-o","w",["pdb","gro"],"amber.pdb","Input pdb/gro file"), -] - +] + # define options @@ -87,7 +87,7 @@ def chain_type(ch): # now check cysteines -print '\nChecking cys....' +print('\nChecking cys....') cysl = model.fetch_residues('CYS') # get a list with all cysteines # we do a simple check. If a HG is there it's CYS, else it's CYS2 @@ -107,30 +107,30 @@ def chain_type(ch): if ss_bond: # terminal cys2 is ccyx rr = 'CYS2' - print 'Residue %d-%s (chain %s) will become %s' % (res.id, res.resname,res.chain_id,rr) + print('Residue %d-%s (chain %s) will become %s' % (res.id, res.resname,res.chain_id,rr)) res.set_resname(rr) else: - print 'Residue %d-%s (chain %s) will become %s' % (res.id, res.resname,res.chain_id,'CYM') + print('Residue %d-%s (chain %s) will become %s' % (res.id, res.resname,res.chain_id,'CYM')) res.set_resname('CYM') - + else: res.set_resname('CYN') - print 'Residue %d-%s (chain %s) will become %s' % (res.id, res.resname, res.chain_id, res.resname) + print('Residue %d-%s (chain %s) will become %s' % (res.id, res.resname, res.chain_id, res.resname)) # lysine -print 'Checking lys....' +print('Checking lys....') lysl = model.fetch_residues('LYS') for res in lysl: at = res.fetch('HZ3') at2 = res.fetch('HZ2') if at or not at2: res.set_resname('LYP') - print 'Residue %d-%s (chain %s) will become %s' % (res.id, 'LYS', res.chain_id, res.resname) - + print('Residue %d-%s (chain %s) will become %s' % (res.id, 'LYS', res.chain_id, res.resname)) + # histidine -print 'Checking his......' +print('Checking his......') hisl = model.fetch_residues('HIS') for res in hisl: bHE2 = False @@ -147,50 +147,50 @@ def chain_type(ch): res.set_resname('HIE') else: res.set_resname('HID') - print 'Residue %d-%s (chain %s) will become %s' % (res.id, 'HIS', res.chain_id, res.resname) + print('Residue %d-%s (chain %s) will become %s' % (res.id, 'HIS', res.chain_id, res.resname)) -print 'Checking asp......' +print('Checking asp......') aspl = model.fetch_residues('ASP') for res in aspl: bHD2 = False hd2 = res.fetch('HD2') if hd2: res.set_resname('ASH') - print 'Residue %d-%s (chain %s) will become %s' % (res.id, 'ASP', res.chain_id, res.resname) + print('Residue %d-%s (chain %s) will become %s' % (res.id, 'ASP', res.chain_id, res.resname)) -print 'Checking glu......' +print('Checking glu......') glul = model.fetch_residues('GLU') for res in glul: bHD2 = False hd2 = res.fetch('HE2') if hd2: res.set_resname('GLH') - print 'Residue %d-%s (chain %s) will become %s' % (res.id, 'GLU', res.chain_id, res.resname) - - + print('Residue %d-%s (chain %s) will become %s' % (res.id, 'GLU', res.chain_id, res.resname)) + -print 'Checking termini.....' + +print('Checking termini.....') for chain in model.chains: - print 'Processing chain %s' % chain.id + print('Processing chain %s' % chain.id) ct = chain_type(chain) - print 'Chain type of chain %s: %s' % (chain.id, ct.upper()) + print('Chain type of chain %s: %s' % (chain.id, ct.upper())) first = chain.residues[0] # first residue last = chain.residues[-1] # last residue if ct == 'pep': - if first.resname in library._one_letter.keys(): + if first.resname in list(library._one_letter.keys()): first.set_resname('N'+first.resname) # rename e.g. ALA to NALA - if last.resname in library._one_letter.keys(): + if last.resname in list(library._one_letter.keys()): if last.resname == 'CYS2': last.set_resname('CCYX') # rename e.g. ARG to CARG else: last.set_resname('C'+last.resname) # rename e.g. ARG to CARG elif last.resname in library._ions: # find last protein residue - print 'Searching last peptide residue in chain %s' % chain.id + print('Searching last peptide residue in chain %s' % chain.id) found = False idx = chain.residues.index(last)-1 while not found: r = chain.residues[idx] - if r.resname in library._one_letter.keys(): + if r.resname in list(library._one_letter.keys()): if r.resname == 'CYS2': r.set_resname('CCYX') else: @@ -209,9 +209,9 @@ def chain_type(ch): o1.name = 'OC1' o2.name = 'OC2' except: - print 'Error: No terminal O1, O2 atoms found in chain %s' % chain.id - print ' In pdb2gmx generated structures these should be there.' - print ' Exiting' + print('Error: No terminal O1, O2 atoms found in chain %s' % chain.id) + print(' In pdb2gmx generated structures these should be there.') + print(' Exiting') sys.exit(1) elif ct in ['dna','rna']: first.set_resname(first.resname+'5') @@ -230,7 +230,7 @@ def chain_type(ch): - + # hack to get pdb file with 4 character residue names #for atom in model.atoms: # atom.chain_id = ' ' @@ -238,8 +238,6 @@ def chain_type(ch): # atom.chain_id = atom.resname[-1]+atom.chain_id model.write(cmdl['-o']) ## fp = open(cmdl['-o'],'w') -## print 'Writing ouput to: %s' % cmdl['-o'] +## print 'Writing ouput to: %s' % cmdl['-o'] ## for atom in model.atoms: ## print >>fp, atom - - diff --git a/pmx/scripts/md_setup.py b/pmx/scripts/md_setup.py index 7a70a42f..7e731c02 100644 --- a/pmx/scripts/md_setup.py +++ b/pmx/scripts/md_setup.py @@ -28,7 +28,7 @@ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # ---------------------------------------------------------------------- import sys,os,shutil -import commands +import subprocess from glob import glob from pmx import * from pmx.ndx import * @@ -42,17 +42,17 @@ def run_command( func, string ): s = func.__name__+'(): '+ string err_file = func.__name__+'_ERROR.log' - status, out = commands.getstatusoutput( string ) + status, out = subprocess.getstatusoutput( string ) if status != 0: - print >>sys.stderr, 'ERROR in %s ' % func.__name__ - print >>sys.stderr, 'Output written to %s' % os.path.abspath(os.path.join('.',err_file)) + print('ERROR in %s ' % func.__name__, file=sys.stderr) + print('Output written to %s' % os.path.abspath(os.path.join('.',err_file)), file=sys.stderr) fp = open(err_file,'w') - print >>fp, s - print >>fp, out + print(s, file=fp) + print(out, file=fp) fp.close() sys.exit(1) else: - print "%-90s" % s, ': ok' + print("%-90s" % s, ': ok') chain_ids = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' @@ -61,15 +61,15 @@ class MD: def __init__(self, **kwargs): self.ff = 'amber99sbmut' - self.water = 'tip3p' + self.water = 'tip3p' self.conc = .15 self.box_type = 'triclinic' self.box_size = 1.2 self.vsite = False self.princ = False - self.md_in_conf = 'md_in.pdb' + self.md_in_conf = 'md_in.pdb' - for key, val in kwargs.items(): + for key, val in list(kwargs.items()): setattr(self,key,val) def setup(self): @@ -95,7 +95,7 @@ def write_residue_map( self, model ): r.old_chain_id = '_' else: chain = r.chain_id - print >>fp, '%d|%s|%s -> %d|%s|%s' %( r.orig_id, r.resname, r.old_chain_id, r.id, r.resname, chain) + print('%d|%s|%s -> %d|%s|%s' %( r.orig_id, r.resname, r.old_chain_id, r.id, r.resname, chain), file=fp) fp.close() def renumber_pdb(self ): @@ -108,7 +108,7 @@ def renumber_pdb(self ): self.write_residue_map( m ) m.write('start.pdb') self.pdb_in = 'start.pdb' - + def __str__(self): s = '< MD (%s) > ' % self.pdb_in return s @@ -117,9 +117,9 @@ def clean_backups(self): files = glob('#*#') for f in files: os.unlink(f) - + def generate_topology(self, pdb_in): - + run = 'pdb2gmx -f %s -water %s -ff %s -o gmx.pdb ' % ( pdb_in, self.water, self.ff ) if self.vsite: run+=' -vsite hydrogens' @@ -134,13 +134,13 @@ def generate_sim_box(self ): else: run = 'editconf -f gmx.pdb -o ed.pdb -d %g -bt %s ' % (self.box_size, self.box_type) run_command( self.generate_sim_box, run) - + def fill_sim_box(self ): if self.water == 'spce': water = 'spc216' else: water = self.water run = 'genbox -cp ed.pdb -cs %s -p -o box.pdb' % os.path.join(ff_path,water) run_command( self.fill_sim_box, run) - + def tpr_from_box(self): run = 'grompp -f ~/mdp/em.mdp -c box.pdb' run_command( self.tpr_from_box, run) @@ -150,28 +150,28 @@ def get_solvent_index(self ): run_command( self.get_solvent_index, run) ndx = IndexFile("tmp.ndx") return ndx.names.index('SOL') - + def add_ions(self ): idx = self.get_solvent_index() run = 'echo %d | genion -conc %g -neutral -p -o ion.pdb' % (idx, self.conc) run_command( self.add_ions, run) - + def make_em_tpr(self): run = 'grompp -f ~/mdp/em.mdp -c ion.pdb' run_command( self.make_em_tpr, run) - + def run_em(self): run = 'mdrun -v -c em.pdb' run_command( self.run_em, run) - + def pdb_from_em(self): - run = 'echo 0| trjconv -f em.pdb -s topol.tpr -o min.pdb' + run = 'echo 0| trjconv -f em.pdb -s topol.tpr -o min.pdb' run_command( self.pdb_from_em, run) - + def compact_repr(self, pdb_in, pdb_out ): run = 'echo 0 | trjconv -f %s -s topol.tpr -ur compact -pbc mol -o %s' % (pdb_in, pdb_out) run_command( self.compact_repr, run) - + class FreeEnergyMD(MD): @@ -179,8 +179,8 @@ class FreeEnergyMD(MD): def __init__(self, mutation_file, **kwargs): MD.__init__( self ) - - for key, val in kwargs.items(): + + for key, val in list(kwargs.items()): setattr(self,key,val) self.mutation_tags = [] self.read_mutation_file( mutation_file ) @@ -189,22 +189,22 @@ def __init__(self, mutation_file, **kwargs): self.mutations_from_tags() self.runs = [] self.is_single_chain = False - + def read_mutation_file(self, mut_file ): - print '\n\t\t\tReading mutation file: %s\n' % mut_file + print('\n\t\t\tReading mutation file: %s\n' % mut_file) l = open(mut_file).readlines() count = 1 for line in l: entr = line.strip() if entr: - print '\t\t\t (%d) -> %s' % (count, entr) + print('\t\t\t (%d) -> %s' % (count, entr)) self.mutation_tags.append( entr ) count+=1 - + def setup(self): self.read_pdb() - print '\n\n' + print('\n\n') for m in self.mutations: self.setup_mutation_run(m) @@ -212,7 +212,7 @@ def read_pdb( self ): self.model = Model(self.md_in_conf) if len(self.model.chains) == 1: self.is_single_chain = True - + def mutations_from_tags(self): for t in self.mutation_tags: mut = t.split() @@ -222,7 +222,7 @@ def mutations_from_tags(self): resid = int(resid) new_mut.append( ( resid, resn, chain ) ) self.mutations.append( new_mut ) - + def setup_mutation_run(self, mutation ): muts = [] affected_chains = [] @@ -238,7 +238,7 @@ def setup_mutation_run(self, mutation ): name+='.dti' elif str(self.__class__).split('.')[1] == 'CrooksMD': name+='.crooks' - print '\n\t\t\tPreparing mutation run -> %s \n' % name + print('\n\t\t\tPreparing mutation run -> %s \n' % name) if os.path.isdir( name ): shutil.rmtree(name) os.mkdir(name) @@ -248,38 +248,38 @@ def setup_mutation_run(self, mutation ): fp = open(script_file,'w') for m in mutation: resid, resn, chain = m - print >>fp, resid, resn + print(resid, resn, file=fp) fp.close() self.make_mutation(name, affected_chains) - + def make_mutation(self, path, affected_chains ): os.chdir(path) run = '~/software/pmx/scripts/mutate_beta45.py -f %s -script mutations.txt -o mut.pdb' % self.md_in_conf run_command( self.make_mutation, run ) self.generate_topology( 'mut.pdb') if self.is_single_chain: - itp_file = 'topol_Protein.itp' + itp_file = 'topol_Protein.itp' run = '~/software/pmx/scripts/make_bstate_beta45.py -itp %s' % itp_file run_command( self.make_mutation, run ) shutil.move(itp_file, itp_file+'.save') shutil.move('newtop.itp', itp_file) else: for chain in affected_chains: - print 'Applying changes to topology of chain %s' % chain + print('Applying changes to topology of chain %s' % chain) itp_file = 'topol_Protein_chain_%s.itp' % chain run = '~/software/pmx/scripts/make_bstate_beta45.py -itp %s' % itp_file run_command( self.make_mutation, run ) shutil.move(itp_file, itp_file+'.save') shutil.move('newtop.itp', itp_file) - os.chdir('..') - + os.chdir('..') + class CrooksMD( FreeEnergyMD ): def __init__(self, mutation_file, **kwargs): FreeEnergyMD.__init__(self, mutation_file) - for key, val in kwargs.items(): + for key, val in list(kwargs.items()): setattr(self,key,val) @@ -289,11 +289,11 @@ def do_crooks( self, mdp_file, min_mdp_file, time, nruns ): self.prepare_min_mdp_files(min_mdp, time ) self.prepare_eq_mdp_files(mdp, time ) for r in self.runs: - print '\n\t\t\tSetting up Crooks run -> %s\n' % r + print('\n\t\t\tSetting up Crooks run -> %s\n' % r) self.minimize_states( r ) self.setup_equilibration_runs( r, nruns ) - + def minimize_states( self, path ): os.chdir(path) @@ -301,41 +301,41 @@ def minimize_states( self, path ): run_command( self.minimize_states, run ) run = 'grompp -f ../crooks_minB.mdp -c gmx.pdb -o minB.tpr' run_command( self.minimize_states, run ) - print '\n\t\t\tRunning energy minimization on %s ( state A ) \n' % ( path ) + print('\n\t\t\tRunning energy minimization on %s ( state A ) \n' % ( path )) run = 'mdrun -v -c emA.pdb -s minA.tpr' run_command( self.minimize_states, run ) - print '\n\t\t\tRunning energy minimization on %s ( state B ) \n' % ( path ) + print('\n\t\t\tRunning energy minimization on %s ( state B ) \n' % ( path )) run = 'mdrun -v -c emB.pdb -s minB.tpr' run_command( self.minimize_states, run ) os.chdir('..') - + def prepare_eq_mdp_files( self, mdp, time ): nsteps = 1000*time/.002 mdp['nsteps'] = nsteps mdp['init-lambda'] = 0 fp = open('crooks_eqA.mdp','w') - print >>fp, mdp + print(mdp, file=fp) fp.close() mdp['init-lambda'] = 1 fp = open('crooks_eqB.mdp','w') - print >>fp, mdp + print(mdp, file=fp) fp.close() def prepare_min_mdp_files( self, mdp, time ): mdp['init-lambda'] = 0 fp = open('crooks_minA.mdp','w') - print >>fp, mdp + print(mdp, file=fp) fp.close() mdp['init-lambda'] = 1 fp = open('crooks_minB.mdp','w') - print >>fp, mdp + print(mdp, file=fp) fp.close() - + def setup_equilibration_runs( self, path, nruns ): os.chdir(path) for i in range(nruns): - print '\n\t\t\tPreparing run input file for %s ( run %d ) \n' % ( path, i ) + print('\n\t\t\tPreparing run input file for %s ( run %d ) \n' % ( path, i )) os.mkdir('runA.%d' % i) os.mkdir('runB.%d' % i) run = 'grompp -f ../crooks_eqA.mdp -c emA.pdb -o runA.%d/topol.tpr' % i @@ -350,9 +350,9 @@ class DiscreteTI( FreeEnergyMD ): def __init__(self, mutation_file, **kwargs): FreeEnergyMD.__init__(self, mutation_file) - for key, val in kwargs.items(): + for key, val in list(kwargs.items()): setattr(self,key,val) - + def read_lambda_steps( self, filename ): l = open(filename).readlines() self.lambda_steps = [] @@ -368,7 +368,7 @@ def prepare_dti_mdp_files( self, mdp_file, time ): for lda in self.lambda_steps: fp = open('dti_%4.3f.mdp' % round(lda,3),'w' ) mdp['init-lambda'] = lda - print >>fp, mdp + print(mdp, file=fp) fp.close() def prepare_dti_min_mdp_files( self, mdp_file): @@ -376,7 +376,7 @@ def prepare_dti_min_mdp_files( self, mdp_file): for lda in self.lambda_steps: fp = open('dti_min_%4.3f.mdp' % round(lda,3),'w' ) mdp['init-lambda'] = lda - print >>fp, mdp + print(mdp, file=fp) fp.close() def setup_runs( self, path ): @@ -386,28 +386,28 @@ def setup_runs( self, path ): run_mdp = 'dti_%4.3f.mdp' % round(lda,3) run_dir = 'run_%4.3f' % round(lda,3) os.mkdir( run_dir ) - print '\n\t\t\tRunning energy minimization on %s/%s \n' % ( path, run_dir ) + print('\n\t\t\tRunning energy minimization on %s/%s \n' % ( path, run_dir )) run = 'grompp -f ../%s -c gmx.pdb -o %s/em.tpr' % (min_mdp, run_dir ) run_command( self.setup_runs, run ) os.chdir( run_dir ) run = 'mdrun -v -c em.pdb -s em.tpr' run_command( self.setup_runs, run ) os.chdir('..') - print '\n\t\t\tPreparing run input file for %s/%s \n' % ( path, run_dir ) + print('\n\t\t\tPreparing run input file for %s/%s \n' % ( path, run_dir )) run = 'grompp -f ../%s -c %s/em.pdb -o %s/topol.tpr' % (run_mdp, run_dir, run_dir ) run_command( self.setup_runs, run ) self.clean_backups() os.chdir( '..') - + def do_dti( self, mdp, min_mdp, time ): self.prepare_dti_min_mdp_files( min_mdp) self.prepare_dti_mdp_files( mdp, time) for r in self.runs: - print '\n\t\t\tSetting up Discrete TI run -> %s\n' % r + print('\n\t\t\tSetting up Discrete TI run -> %s\n' % r) self.setup_runs( r ) - + def main(argv): version = "1.0" @@ -425,7 +425,7 @@ def main(argv): Option( "-crooks_run_time", "float", 50., "Simulation time [ns] for crooks equilibrium runs"), Option( "-skip_md_setup", "bool", False, "skip md setup and use -f as starting configuration for free energy runs"), ] - + files = [ FileOption("-f", "r",["pdb"],"protein", "input pdb file"), FileOption("-m", "r/o",["txt"],"mutations", "mutations to make"), @@ -434,13 +434,13 @@ def main(argv): FileOption("-min_mdp", "r/o",["mdp"],"em", "template minimization mdp file ( for TI or Crooks )"), FileOption("-lambda_steps", "r/o",["txt"],"lambda_steps", "text file with lambda steps for DTI runs"), ] - - - + + + help_text = ("Script for setting up plain MD runs", ) - + cmdl = Commandline( argv, options = options, fileoptions = files, program_desc = help_text, @@ -455,15 +455,15 @@ def main(argv): try: open(mutation_file).readlines() except: - print >>sys.stderr, 'Error: Cannot open %s' % mutation_file + print('Error: Cannot open %s' % mutation_file, file=sys.stderr) sys.exit(1) if cmdl['-fe.dti']: # require lambda steps try: open(cmdl['-lambda_steps']).readlines() except: - print >>sys.stderr, 'Error: Cannot open %s' % cmdl['-lambda_steps'] + print('Error: Cannot open %s' % cmdl['-lambda_steps'], file=sys.stderr) sys.exit(1) - + pdb_in = cmdl['-f'] @@ -474,9 +474,9 @@ def main(argv): free_energy_start_pdb = None bVsite = cmdl['-vsite'] if bVsite and bFreeEnergy: - print >>sys.stderr, 'Error: Cannot use virtual sites in free energy calculations !' + print('Error: Cannot use virtual sites in free energy calculations !', file=sys.stderr) sys.exit(1) - + if not cmdl['-skip_md_setup']: md = MD( pdb_in = pdb_in, water = water, conc = conc, box_type = box_type, box_size = box_size ) @@ -484,7 +484,7 @@ def main(argv): free_energy_start_pdb = md.md_in_conf else: if not bFreeEnergy: - print 'Nothing to do........... (no MD, no Free Energy)' + print('Nothing to do........... (no MD, no Free Energy)') sys.exit() if bFreeEnergy: if not free_energy_start_pdb: @@ -501,8 +501,8 @@ def main(argv): dti.do_dti(cmdl['-dti_mdp'], cmdl['-min_mdp'], cmdl['-dti_run_time'] ) - print '\n\t\t\t ....... DONE .......... \n' - + print('\n\t\t\t ....... DONE .......... \n') + ## n_crooks_runs = cmdl['-n_crooks_runs'] @@ -516,9 +516,9 @@ def main(argv): ## if cmdl.opt['-min_mdp'].is_set: ## min_mdp = MDP().read( cmdl['-min_mdp'] ) ## if cmdl.opt['-lambda_steps'].is_set: -## lambda_file = cmdl['-lambda_steps'] - - +## lambda_file = cmdl['-lambda_steps'] + + ## md = MD( pdb_in = pdb_in, water = water, conc = conc, box_type = box_type, box_size = box_size ) ## # md.setup() @@ -528,15 +528,15 @@ def main(argv): ## dti.do_dti(mdp, min_mdp, 10. ) - + ## crooksMD = CrooksMD( mut_file, md_in_conf = md.md_in_conf) ## crooksMD.setup() ## crooksMD.do_crooks(mdp, 20, cmdl['-n_crooks_runs']) - + # fe_md = FreeEnergyMD( mutations, md_in_conf = md.md_in_conf ) # fe_md.setup() - - + + ## generate_topology(pdb_in, water, 'amber99sbmut') ## generate_sim_box( box_type, box_size ) ## fill_sim_box( water ) @@ -553,5 +553,3 @@ def main(argv): if __name__=='__main__': main( sys.argv ) - - diff --git a/pmx/scripts/mutate.py b/pmx/scripts/mutate.py index 1f9c6c55..949d390b 100755 --- a/pmx/scripts/mutate.py +++ b/pmx/scripts/mutate.py @@ -208,13 +208,13 @@ def check_residue_name( res ): res.set_resname('GLH') elif res.resname == 'CYS': if not res.has_atom('HG'): - print >>sys.stderr,' Cannot mutate SS-bonded Cys %d' % res.id + print(' Cannot mutate SS-bonded Cys %d' % res.id, file=sys.stderr) def check_OPLS_LYS( res ): if res.has_atom( 'HZ3'): return('K') else: - return('O') + return('O') #def get_restype(r): # if r.resname in ['DA','DT','DC','DG']: @@ -227,33 +227,33 @@ def read_script(fn): return read_and_format(fn,"is") def int_input(): - inp = raw_input() + inp = input() try: inp = int(inp) return inp except: - print 'You entered "%s" -> Try again' % inp + print('You entered "%s" -> Try again' % inp) return None def check_residue_range(m, idx): - valid_ids = range(1, len(m.residues)+1) + valid_ids = list(range(1, len(m.residues)+1)) if idx not in valid_ids: return False return True def select_residue(m): - valid_ids = range(1, len(m.residues)+1) - print '\nSelect residue to mutate:' + valid_ids = list(range(1, len(m.residues)+1)) + print('\nSelect residue to mutate:') for i,r in enumerate(m.residues): if r.resname not in library._ions+library._water: sys.stdout.write('%6d-%s-%s' % (r.id,r.resname,r.chain_id)) - if r.id % 6 == 0: print - print + if r.id % 6 == 0: print() + print() selected_residue_id = None while not selected_residue_id: sys.stdout.write('Enter residue number: ') selected_residue_id = int_input() if selected_residue_id is not None and selected_residue_id not in valid_ids: - print 'Residue id %d not in range %d-%d -> Try again' % (selected_residue_id,1,len(residues)) + print('Residue id %d not in range %d-%d -> Try again' % (selected_residue_id,1,len(residues))) selected_residue_id = None return selected_residue_id @@ -267,10 +267,10 @@ def select_mutation(m, selected_residue_id, ffpath): def select_nuc_mutation(residue): aa = None - print '\nSelect new base for %s-%s: ' % (residue.id,residue.resname) + print('\nSelect new base for %s-%s: ' % (residue.id,residue.resname)) sys.stdout.write('One-letter code: ') while aa is None: - aa = raw_input().upper() + aa = input().upper() if get_restype(residue) == 'DNA' and aa not in ['A','C','G','T']: sys.stdout.write('Unknown DNA residue "%s"!\nOne-letter code: ' % aa) aa = None @@ -278,12 +278,12 @@ def select_nuc_mutation(residue): sys.stdout.write('Unknown RNA residue "%s"!\nOne-letter code: ' % aa) aa = None if aa: - print 'Will apply mutation %s->%s on residue %s-%d' % (residue.resname[1],aa,residue.resname,residue.id) + print('Will apply mutation %s->%s on residue %s-%d' % (residue.resname[1],aa,residue.resname,residue.id)) return aa def select_aa_mutation(residue,ffpath): check_residue_name( residue ) - print '\nSelect new amino acid for %s-%s: ' % (residue.id,residue.resname) + print('\nSelect new amino acid for %s-%s: ' % (residue.id,residue.resname)) sys.stdout.write('Three- or one-letter code (or four-letter for ff specific residues): ') if residue.resname in ['HIE','HISE','HSE']: rol = 'X' elif residue.resname in ['HIP','HISH','HSP']: rol = 'Z' @@ -293,21 +293,21 @@ def select_aa_mutation(residue,ffpath): else: rol = library._one_letter[residue.resname] aa = None - ol = library._aacids_dic.keys() - tl = library._aacids_dic.values() + ol = list(library._aacids_dic.keys()) + tl = list(library._aacids_dic.values()) ffpathlower = ffpath.lower() if('amber' in ffpathlower): - ol = library._aacids_ext_amber.keys() - tl = library._aacids_ext_amber.values() + ol = list(library._aacids_ext_amber.keys()) + tl = list(library._aacids_ext_amber.values()) if('opls' in ffpathlower): - ol = library._aacids_ext_oplsaa.keys() - tl = library._aacids_ext_oplsaa.values()+['ASPP','GLUP','LSN'] + ol = list(library._aacids_ext_oplsaa.keys()) + tl = list(library._aacids_ext_oplsaa.values())+['ASPP','GLUP','LSN'] if('charmm' in ffpathlower): - ol = library._aacids_ext_charmm.keys() - tl = library._aacids_ext_charmm.values() + ol = list(library._aacids_ext_charmm.keys()) + tl = list(library._aacids_ext_charmm.values()) while aa is None: - aa = raw_input().upper() + aa = input().upper() if len(aa) != 1 and len(aa)!=3 and len(aa)!=4: sys.stdout.write('Nope!\nThree- or one-letter code (or four-letter for ff specific residues): ') aa = None @@ -315,7 +315,7 @@ def select_aa_mutation(residue,ffpath): sys.stdout.write('Unknown aa "%s"!\nThree- or one-letter code (or four-letter for ff specific residues): ' % aa) aa = None if aa and (len(aa)==3 or len(aa)==4): aa = ext_one_letter[aa] - print 'Will apply mutation %s->%s on residue %s-%d' % (rol,aa,residue.resname,residue.id) + print('Will apply mutation %s->%s on residue %s-%d' % (rol,aa,residue.resname,residue.id)) return aa @@ -326,7 +326,7 @@ def interactive_selection(m,ffpath): def ask_next(): sys.stdout.write('\nApply another mutation [y/n]? ') - res = raw_input().lower() + res = input().lower() if res == 'y': return True elif res == 'n': return False else: return ask_next() @@ -342,23 +342,23 @@ def rename_to_match_library(res): name_hash = {} atoms = res.atoms for atom in atoms: - foo = atom.name - ## for serine - if (atom.resname == 'SER') and (atom.name == 'HG1'): - atom.name = 'HG' + foo = atom.name + ## for serine + if (atom.resname == 'SER') and (atom.name == 'HG1'): + atom.name = 'HG' if ('S2' in atom.resname) and (atom.name == 'HG1'): atom.name = 'HG' if ('SP1' in atom.resname) and (atom.name == 'HG1'): # phosphoserine in charmm36 atom.name = 'HG' if ('SP2' in atom.resname) and (atom.name == 'HG1'): # phosphoserine in charmm36 atom.name = 'HG' - ## for cysteine + ## for cysteine if (atom.resname == 'CYS') and (atom.name == 'HG1'): atom.name = 'HG' if ('C2' in atom.resname) and (atom.name == 'HG1'): atom.name = 'HG' -# print atom.resname,atom.name - name_hash[atom.name] = foo +# print atom.resname,atom.name + name_hash[atom.name] = foo return name_hash def rename_back( res, name_hash ): @@ -368,11 +368,11 @@ def rename_back( res, name_hash ): def set_conformation(old_res, new_res, rotdic): old_res.get_real_resname() dihedrals = library._aa_dihedrals[old_res.real_resname] - for key, lst in rotdic.items(): + for key, lst in list(rotdic.items()): new = new_res.fetchm(lst) rotdic[key] = new chis = [] - for key in rotdic.keys(): + for key in list(rotdic.keys()): at1,at2 = key.split('-') for d in dihedrals: if d[1] == at1 and d[2] == at2 \ @@ -398,28 +398,28 @@ def set_conformation(old_res, new_res, rotdic): def get_nuc_hybrid_resname(residue,new_nuc_name,bRNA=False): firstLetter = 'D' if bRNA: - firstLetter = 'R' + firstLetter = 'R' # identify if the nucleotide is terminal for a in residue.atoms: - if a.name=='H3T': - r1 = firstLetter+residue.resname[1]+'3' - r2 = firstLetter+new_nuc_name+'3' - dict_key = r1+'_'+r2 - if bRNA: - hybrid_residue_name = rna_names[dict_key] - else: - hybrid_residue_name = dna_names[dict_key] - return(hybrid_residue_name,residue.resname[1],new_nuc_name) - elif a.name=='H5T': - r1 = firstLetter+residue.resname[1]+'5' - r2 = firstLetter+new_nuc_name+'5' - dict_key = r1+'_'+r2 - if bRNA: - hybrid_residue_name = rna_names[dict_key] - else: - hybrid_residue_name = dna_names[dict_key] - return(hybrid_residue_name,residue.resname[1],new_nuc_name) + if a.name=='H3T': + r1 = firstLetter+residue.resname[1]+'3' + r2 = firstLetter+new_nuc_name+'3' + dict_key = r1+'_'+r2 + if bRNA: + hybrid_residue_name = rna_names[dict_key] + else: + hybrid_residue_name = dna_names[dict_key] + return(hybrid_residue_name,residue.resname[1],new_nuc_name) + elif a.name=='H5T': + r1 = firstLetter+residue.resname[1]+'5' + r2 = firstLetter+new_nuc_name+'5' + dict_key = r1+'_'+r2 + if bRNA: + hybrid_residue_name = rna_names[dict_key] + else: + hybrid_residue_name = dna_names[dict_key] + return(hybrid_residue_name,residue.resname[1],new_nuc_name) hybrid_residue_name = residue.resname+new_nuc_name return(hybrid_residue_name,residue.resname[1],new_nuc_name) @@ -427,9 +427,9 @@ def apply_nuc_mutation(m, residue, new_nuc_name, mtp_file, bRNA=False): # hybrid_residue_name = residue.resname+new_nuc_name hybrid_residue_name,resname1,resname2 = get_nuc_hybrid_resname(residue,new_nuc_name,bRNA) - print 'log_> Residue to mutate: %d | %s | %s ' % ( residue.id, residue.resname, residue.chain_id) - print 'log_> Mutation to apply: %s->%s' % (residue.resname[1], new_nuc_name) - print 'log_> Hybrid residue name: %s' % hybrid_residue_name + print('log_> Residue to mutate: %d | %s | %s ' % ( residue.id, residue.resname, residue.chain_id)) + print('log_> Mutation to apply: %s->%s' % (residue.resname[1], new_nuc_name)) + print('log_> Hybrid residue name: %s' % hybrid_residue_name) hybrid_res, bonds, imps, diheds, rotdic = get_hybrid_residue(hybrid_residue_name, mtp_file) # hybrid_res.nm2a() @@ -438,8 +438,8 @@ def apply_nuc_mutation(m, residue, new_nuc_name, mtp_file, bRNA=False): if atom.name[0] != 'D': atom.x = residue[atom.name].x m.replace_residue( residue, hybrid_res) - print 'log_> Inserted hybrid residue %s at position %d (chain %s)' %\ - (hybrid_res.resname, hybrid_res.id, hybrid_res.chain_id) + print('log_> Inserted hybrid residue %s at position %d (chain %s)' %\ + (hybrid_res.resname, hybrid_res.id, hybrid_res.chain_id)) def apply_aa_mutation(m, residue, new_aa_name, mtp_file, bStrB, infileB): @@ -454,13 +454,13 @@ def apply_aa_mutation(m, residue, new_aa_name, mtp_file, bStrB, infileB): olkey = check_OPLS_LYS( residue ) hybrid_residue_name = olkey+'2'+new_aa_name - if hybrid_residue_name in noncanonical_aa.keys(): + if hybrid_residue_name in list(noncanonical_aa.keys()): hybrid_residue_name = noncanonical_aa[hybrid_residue_name] # if hybrid_residue_name in longname_aa.keys(): # hybrid_residue_name = longname_aa[hybrid_residue_name] - print 'log_> Residue to mutate: %d | %s | %s ' % ( residue.id, residue.resname, residue.chain_id) - print 'log_> Mutation to apply: %s->%s' % (olkey, new_aa_name) - print 'log_> Hybrid residue name: %s' % hybrid_residue_name + print('log_> Residue to mutate: %d | %s | %s ' % ( residue.id, residue.resname, residue.chain_id)) + print('log_> Mutation to apply: %s->%s' % (olkey, new_aa_name)) + print('log_> Hybrid residue name: %s' % hybrid_residue_name) hybrid_res, bonds, imps, diheds, rotdic = get_hybrid_residue(hybrid_residue_name, mtp_file) #hybrid_res.nm2a() bb_super(residue, hybrid_res ) @@ -470,24 +470,24 @@ def apply_aa_mutation(m, residue, new_aa_name, mtp_file, bStrB, infileB): hash2 = rename_to_match_library(hybrid_res) set_conformation(residue, hybrid_res, rotdic) if bStrB: - print "log_> Set Bstate geometry according to the provided structure" - mB = Model(infileB,bPDBTER=True) - rename_atoms_to_gromacs( mB ) - mB.nm2a() - residueB = mB.residues[residue.id-1] - bb_super(residue, residueB ) - for atom in hybrid_res.atoms: + print("log_> Set Bstate geometry according to the provided structure") + mB = Model(infileB,bPDBTER=True) + rename_atoms_to_gromacs( mB ) + mB.nm2a() + residueB = mB.residues[residue.id-1] + bb_super(residue, residueB ) + for atom in hybrid_res.atoms: if atom.name[0] == 'D': - for atomB in residueB.atoms: - if atomB.name == hybrid_res.morphes[atom.name]['n1']: - atom.x = atomB.x + for atomB in residueB.atoms: + if atomB.name == hybrid_res.morphes[atom.name]['n1']: + atom.x = atomB.x rename_back(residue,hash1) rename_back(hybrid_res,hash2) ## VG rename residue atoms back m.replace_residue( residue, hybrid_res) - print 'log_> Inserted hybrid residue %s at position %d (chain %s)' %\ - (hybrid_res.resname, hybrid_res.id, hybrid_res.chain_id) + print('log_> Inserted hybrid residue %s at position %d (chain %s)' %\ + (hybrid_res.resname, hybrid_res.id, hybrid_res.chain_id)) def apply_mutation(m, mut, mtp_file, bStrB, infileB, bRNA): @@ -504,7 +504,7 @@ def apply_mutation(m, mut, mtp_file, bStrB, infileB, bRNA): def get_hybrid_residue(residue_name, mtp_file = 'ffamber99sb.mtp'): - print 'log_> Scanning database for %s ' % residue_name + print('log_> Scanning database for %s ' % residue_name) resi, bonds, imps, diheds, rotdic = read_mtp_entry(residue_name, filename = mtp_file, version = 'new') if len(resi.atoms) == 0: raise mtpError("Hybrid residue %s not found in %s" % (residue_name, mtp_file) ) @@ -518,7 +518,7 @@ def rename_ile(residue): 'HD2':'HD12', 'HD3':'HD13' } - for key, value in dic.items(): + for key, value in list(dic.items()): try: atom = residue[key] atom.name = value @@ -552,120 +552,120 @@ def get_ff_path( ff ): elif os.path.isdir(pff): ff_path = pff else: - print >>sys.stderr,' Error: forcefield path "%s" not found' % ff + print(' Error: forcefield path "%s" not found' % ff, file=sys.stderr) sys.exit(0) else: ff_path = ff - print 'Opening forcefield: %s' % ff_path + print('Opening forcefield: %s' % ff_path) return ff_path def main(argv): - options = [ - Option( "-resinfo", "bool", False, "print a 3-letter -> 1-letter residue list"), - Option( "-dna", "bool", False, "generate hybrid residue for the DNA nucleotides"), - Option( "-rna", "bool", False, "generate hybrid residue for the RNA nucleotides"), -## Option( "-r", "rvec", [1,2,3], "some string"), -## Option( "-b", "bool", True, "bool"), -## Option( "-r2", "rvec", [1,2,3], "some vector that does wonderful things and returns always segfaults") + options = [ + Option( "-resinfo", "bool", False, "print a 3-letter -> 1-letter residue list"), + Option( "-dna", "bool", False, "generate hybrid residue for the DNA nucleotides"), + Option( "-rna", "bool", False, "generate hybrid residue for the RNA nucleotides"), + ## Option( "-r", "rvec", [1,2,3], "some string"), + ## Option( "-b", "bool", True, "bool"), + ## Option( "-r2", "rvec", [1,2,3], "some vector that does wonderful things and returns always segfaults") + ] + + files = [ + FileOption("-f", "r",["pdb","gro"],"protein.pdb", "input structure file"), + FileOption("-fB", "r",["pdb","gro"],"proteinB.pdb", "input structure file of the Bstate (optional)"), + FileOption("-o", "w",["pdb","gro"],"out.pdb", "output structure file"), + FileOption("-ff", "dir",["ff"],"amber99sbmut", "path to mutation forcefield"), + FileOption("-script", "r",["txt"],"mutations.txt", "text file with mutations to insert"), ] - files = [ - FileOption("-f", "r",["pdb","gro"],"protein.pdb", "input structure file"), - FileOption("-fB", "r",["pdb","gro"],"proteinB.pdb", "input structure file of the Bstate (optional)"), - FileOption("-o", "w",["pdb","gro"],"out.pdb", "output structure file"), - FileOption("-ff", "dir",["ff"],"amber99sbmut", "path to mutation forcefield"), - FileOption("-script", "r",["txt"],"mutations.txt", "text file with mutations to insert"), - ] - - help_text = ('This script applies mutations of residues in a structure file ', - 'for subsequent free energy calculations like FEP, TI, etc.', - 'The mutation information and dummy placements are taken from', - 'the hybrid residue database "mutres.mtp". The best way to use', - 'this script is to take a pdb/gro file that has been written with pdb2gmx', - 'with all hydrogen atoms present.' - 'The program can either be executed interactively or via script.', - 'The script file simply has to consist of "resi_number target_residue." pairs.', - 'The script uses an extended one-letter code for amino acids to account for', - 'different protonation states. Use the -resinfo flag to print the dictionary.', - 'Currently available force fields:', - ' - amber99sbmut (Hornak et al, 2006)', - ' - amber99sb-star-ildn-mut (Best & Hummer, 2009; Lindorff-Larsen et al, 2010)', - ' - charmm22starmut.ff (Piana et al, 2011)', - ' - charmm36mut (Best et al, 2012)', - ' - oplsaamut (Jorgensen et al, 1996; Kaminski et al, 2001)', - '', - '', - 'Please cite:', - 'Vytautas Gapsys, Servaas Michielssens, Daniel Seeliger and Bert L. de Groot.', - 'Automated Protein Structure and Topology Generation for Alchemical Perturbations.', - 'J. Comput. Chem. 2015, 36, 348-354. DOI: 10.1002/jcc.23804', - '', - 'Old pmx (pymacs) version:', - 'Daniel Seeliger and Bert L. de Groot. Protein Thermostability Calculations Using', - 'Alchemical Free Energy Simulations, Biophysical Journal, 98(10):2309-2316 (2010)', - '', - '', - '', - ) - - - cmdl = Commandline( argv, options = options, - fileoptions = files, - program_desc = help_text, - check_for_existing_files = False ) - - bDNA = cmdl['-dna'] - bRNA = cmdl['-rna'] - - if cmdl['-resinfo']: - print 'Residue dictionary:' - lst = ext_one_letter.items() - lst.sort(lambda a,b: cmp(a,b)) - for key, val in lst: - print "%5s %4s" % (key, val) - sys.exit(0) - - bStrB = False - infileB = '' - if cmdl.opt['-fB'].is_set: - bStrB = True - infileB = cmdl['-fB'] - - ffpath = get_ff_path(cmdl['-ff']) - if bDNA: - mtp_file = os.path.join( ffpath,'mutres_dna.mtp') - elif bRNA: - mtp_file = os.path.join( ffpath,'mutres_rna.mtp') - else: - mtp_file = os.path.join( ffpath,'mutres.mtp') - infile = cmdl['-f'] - - m = Model(infile,bPDBTER=True) - - rename_atoms_to_gromacs( m ) + help_text = ('This script applies mutations of residues in a structure file ', + 'for subsequent free energy calculations like FEP, TI, etc.', + 'The mutation information and dummy placements are taken from', + 'the hybrid residue database "mutres.mtp". The best way to use', + 'this script is to take a pdb/gro file that has been written with pdb2gmx', + 'with all hydrogen atoms present.' + 'The program can either be executed interactively or via script.', + 'The script file simply has to consist of "resi_number target_residue." pairs.', + 'The script uses an extended one-letter code for amino acids to account for', + 'different protonation states. Use the -resinfo flag to print the dictionary.', + 'Currently available force fields:', + ' - amber99sbmut (Hornak et al, 2006)', + ' - amber99sb-star-ildn-mut (Best & Hummer, 2009; Lindorff-Larsen et al, 2010)', + ' - charmm22starmut.ff (Piana et al, 2011)', + ' - charmm36mut (Best et al, 2012)', + ' - oplsaamut (Jorgensen et al, 1996; Kaminski et al, 2001)', + '', + '', + 'Please cite:', + 'Vytautas Gapsys, Servaas Michielssens, Daniel Seeliger and Bert L. de Groot.', + 'Automated Protein Structure and Topology Generation for Alchemical Perturbations.', + 'J. Comput. Chem. 2015, 36, 348-354. DOI: 10.1002/jcc.23804', + '', + 'Old pmx (pymacs) version:', + 'Daniel Seeliger and Bert L. de Groot. Protein Thermostability Calculations Using', + 'Alchemical Free Energy Simulations, Biophysical Journal, 98(10):2309-2316 (2010)', + '', + '', + '', + ) + + + cmdl = Commandline( argv, options = options, + fileoptions = files, + program_desc = help_text, + check_for_existing_files = False ) + + bDNA = cmdl['-dna'] + bRNA = cmdl['-rna'] + + if cmdl['-resinfo']: + print('Residue dictionary:') + lst = list(ext_one_letter.items()) + lst.sort(lambda a,b: cmp(a,b)) + for key, val in lst: + print("%5s %4s" % (key, val)) + sys.exit(0) + + bStrB = False + infileB = '' + if cmdl.opt['-fB'].is_set: + bStrB = True + infileB = cmdl['-fB'] + + ffpath = get_ff_path(cmdl['-ff']) + if bDNA: + mtp_file = os.path.join( ffpath,'mutres_dna.mtp') + elif bRNA: + mtp_file = os.path.join( ffpath,'mutres_rna.mtp') + else: + mtp_file = os.path.join( ffpath,'mutres.mtp') + infile = cmdl['-f'] + + m = Model(infile,bPDBTER=True) + + rename_atoms_to_gromacs( m ) # m.write('ll.pdb') - m.nm2a() + m.nm2a() # m.rename_atoms() - mutation_list = [] - if cmdl.opt['-script'].is_set: - mutations_to_make = read_script( cmdl['-script'] ) - for mut in mutations_to_make: - check_residue_name( m.residues[ mut[0]-1 ] ) - apply_mutation( m, mut, mtp_file, bStrB, infileB, bRNA ) - else: - do_more = True - while do_more: - mutation = interactive_selection(m,ffpath) - apply_mutation( m, mutation, mtp_file, bStrB, infileB, bRNA ) - if not ask_next(): do_more = False - - - m.write(cmdl['-o'],bPDBTER=True) - print - print 'mutations done...........' - print + mutation_list = [] + if cmdl.opt['-script'].is_set: + mutations_to_make = read_script( cmdl['-script'] ) + for mut in mutations_to_make: + check_residue_name( m.residues[ mut[0]-1 ] ) + apply_mutation( m, mut, mtp_file, bStrB, infileB, bRNA ) + else: + do_more = True + while do_more: + mutation = interactive_selection(m,ffpath) + apply_mutation( m, mutation, mtp_file, bStrB, infileB, bRNA ) + if not ask_next(): do_more = False + + + m.write(cmdl['-o'],bPDBTER=True) + print() + print('mutations done...........') + print() def entry_point(): diff --git a/pmx/scripts/prepare_crooks_runs.py b/pmx/scripts/prepare_crooks_runs.py index 772bbbd9..50326d77 100644 --- a/pmx/scripts/prepare_crooks_runs.py +++ b/pmx/scripts/prepare_crooks_runs.py @@ -30,7 +30,7 @@ # ---------------------------------------------------------------------- import sys, os, shutil -import commands +import subprocess from glob import glob from pmx.forcefield import MDP from pmx import * @@ -38,17 +38,17 @@ def run_command( func, string ): s = func.__name__+'(): '+ string err_file = func.__name__+'_ERROR.log' - status, out = commands.getstatusoutput( string ) + status, out = subprocess.getstatusoutput( string ) if status != 0: - print >>sys.stderr, 'ERROR in %s ' % func.__name__ - print >>sys.stderr, 'Output written to %s' % err_file + print('ERROR in %s ' % func.__name__, file=sys.stderr) + print('Output written to %s' % err_file, file=sys.stderr) fp = open(err_file,'w') - print >>fp, s - print >>fp, out + print(s, file=fp) + print(out, file=fp) fp.close() sys.exit(1) else: - print "%-90s" % s, ': ok' + print("%-90s" % s, ': ok') @@ -57,13 +57,13 @@ def make_dir_tree( skip = 4): # catch all run?.? dirs dirs = glob('run?.?') for d in dirs: - print '\tPreparing run %s' % d + print('\tPreparing run %s' % d) os.chdir(d) os.mkdir('morphes') cmd = 'echo 0| trjconv -f traj.trr -s topol.tpr -skip %d -b 2001 -sep -o morphes/frame.gro' % skip run_command(make_dir_tree, cmd ) os.chdir('morphes') - + # put each file into single directory file_list = glob('frame*.gro') for f in file_list: @@ -72,11 +72,11 @@ def make_dir_tree( skip = 4): shutil.move(f,name) os.chdir('..') os.chdir('..') - + def prepare_mdp_files( template_mdp, sw_time, sc_alpha, sc_sigma ): mdp = MDP().read( template_mdp ) - + # make 0->1 file mdp['free-energy'] = 'yes' mdp['init-lambda'] = 0 @@ -88,30 +88,30 @@ def prepare_mdp_files( template_mdp, sw_time, sc_alpha, sc_sigma ): mdp['delta-lambda'] = delta_lambda mdp['sc-alpha'] = sc_alpha mdp['sc-sigma'] = sc_sigma - + fp = open('crooks_TI_runA.mdp','w') - print >>fp, mdp + print(mdp, file=fp) fp.close() - + # make 1->0 file mdp['init-lambda'] = 1 mdp['delta-lambda'] = -delta_lambda - + fp = open('crooks_TI_runB.mdp','w') - print >>fp, mdp + print(mdp, file=fp) fp.close() - + def make_run_input_files(): - + dirs = glob('run?.?') for d in dirs: - print '\n\tPreparing run input files %s' % d + print('\n\tPreparing run input files %s' % d) mdp_file = None if d.split('.')[0][-1] == 'A': # 0->1 mdp_file = 'crooks_TI_runA.mdp' elif d.split('.')[0][-1] == 'B': # 1->0 - mdp_file = 'crooks_TI_runB.mdp' + mdp_file = 'crooks_TI_runB.mdp' dir_list = glob(os.path.join(d,'morphes')+'/frame*') for f in dir_list: fname = os.path.basename(f)+'.gro' @@ -119,8 +119,8 @@ def make_run_input_files(): cmd = 'grompp -f %s -c %s -o %s/topol.tpr' % (mdp_file, gro_file, f) run_command( make_run_input_files, cmd ) os.system( 'rm mdout.mdp ') - - + + def main(argv): version = "1.0" @@ -130,7 +130,7 @@ def main(argv): Option( "-sc_alpha", "real", 0.3, "soft-core alpha"), Option( "-sc_sigma", "real", 0.25, "soft-core sigma"), Option( "-skip", "int", 4, "skip # frames"), - + ## Option( "-box_size", "float", 1.2, "distance from solute to box"), ## Option( "-conc", "float", 0.15, "ion concentration"), ## Option( "-vsite", "bool", False, "use virtual sites"), @@ -140,9 +140,9 @@ def main(argv): ## Option( "-n_crooks_runs", "int", 1, "setup # crooks runs for each mutation"), ## Option( "-crooks_run_time", "float", 50., "Simulation time [ns] for crooks equilibrium runs"), ## Option( "-skip_md_setup", "bool", False, "skip md setup and use -f as starting configuration for free energy runs") - + ] - + files = [ FileOption("-d", "r",["dir"],"", "directory with equlibrated states"), FileOption("-mdp", "r",["mdp"],"TI_template.mdp", "template TI mdp file"), @@ -151,13 +151,13 @@ def main(argv): ## FileOption("-min_mdp", "r/o",["mdp"],"em", "template minimization mdp file ( for TI or Crooks )"), ## FileOption("-lambda_steps", "r/o",["txt"],"lambda_steps", "text file with lambda steps for DTI runs"), ] - - - + + + help_text = ("Script for setting up plain FGTI runs", ) - + cmdl = Commandline( argv, options = options, fileoptions = files, program_desc = help_text, @@ -171,30 +171,29 @@ def main(argv): sw_time = cmdl['-sw_time'] sc_alpha = cmdl['-sc_alpha'] sc_sigma = cmdl['-sc_sigma'] - - print '\n\t Preparing FGTI runs in directory..: %s' % run_dir - print '\t Template mdp file to use............: %s' % mdp_file - print '\t Switching time to use...............: %8d ps' % int( sw_time ) - print '\t Soft-core alpha to use..............: %8.3f' % sc_alpha - print '\t Soft-core sigma to use..............: %8.3f' % sc_sigma - print '\n' - - - os.chdir( run_dir ) - - print '\t Preparing mdp input files........... ' - + + print('\n\t Preparing FGTI runs in directory..: %s' % run_dir) + print('\t Template mdp file to use............: %s' % mdp_file) + print('\t Switching time to use...............: %8d ps' % int( sw_time )) + print('\t Soft-core alpha to use..............: %8.3f' % sc_alpha) + print('\t Soft-core sigma to use..............: %8.3f' % sc_sigma) + print('\n') + + + os.chdir( run_dir ) + + print('\t Preparing mdp input files........... ') + prepare_mdp_files( mdp_file, sw_time, sc_alpha, sc_sigma ) - - - print '\t Preparing directory tree............ ' + + + print('\t Preparing directory tree............ ') make_dir_tree(skip = cmdl['-skip']) make_run_input_files() os.chdir( here ) - print '\n\t............... DONE .................\n' + print('\n\t............... DONE .................\n') if __name__=='__main__': - - main( sys.argv ) + main( sys.argv ) diff --git a/pmx/scripts/set_gmxlib.py b/pmx/scripts/set_gmxlib.py index a1c080d4..b0053dbb 100755 --- a/pmx/scripts/set_gmxlib.py +++ b/pmx/scripts/set_gmxlib.py @@ -13,12 +13,12 @@ def main(): ' available in pmx, the environment variable GMXLIB needs to be set.\n') print(' The path to your pmx force field library for proteins is:') - print(' %s\n' % gmxlib_proteins) + print((' %s\n' % gmxlib_proteins)) print(' The path to your pmx force field library for nucleic acids is:') - print(' %s\n' % gmxlib_nuc_acids) + print((' %s\n' % gmxlib_nuc_acids)) print(' Set the relevant GMXLIB path in your shell session as follows:') - print(' $ export GMXLIB=%s\n' % gmxlib_proteins) + print((' $ export GMXLIB=%s\n' % gmxlib_proteins)) print(' Or you can add this directly in your bashrc file.\n') diff --git a/pmx/tCNC.py b/pmx/tCNC.py index 936dd9f9..0af4bb8e 100644 --- a/pmx/tCNC.py +++ b/pmx/tCNC.py @@ -33,9 +33,9 @@ """ import sys, os -from parser import * +from .parser import * from numpy import * -import library +from . import library def read_atom_types(f): if hasattr(f,"read"): @@ -68,65 +68,65 @@ def read_atom_types(f): def make_lib_dic(f): keys, dic = read_atom_types(f) - print 'atom_types = {' + print('atom_types = {') for key in keys: val = dic[key] - print "\t'%s': {" % key - for name, entr in val.items(): - print "\t\t\"%s\" : {" % name - print "\t\t\t'type':'%s'," % entr['type'] - print "\t\t\t'hyb':'%s'" % entr['hyb'] - print "\t\t}," - print "\t}," - print "}" + print("\t'%s': {" % key) + for name, entr in list(val.items()): + print("\t\t\"%s\" : {" % name) + print("\t\t\t'type':'%s'," % entr['type']) + print("\t\t\t'hyb':'%s'" % entr['hyb']) + print("\t\t},") + print("\t},") + print("}") + - def assign_types(model,verbose=False): atom_types = library._atom_types # default first dic = atom_types['DEFAULT'] for atom in model.atoms: name = atom.long_name.strip() - if dic.has_key(name): + if name in dic: atom.atype = dic[name]['type'] atom.hyb = dic[name]['hyb'] #if isinstance(model,pmx.Model) or isinstance(model,pmx.Chain): if hasattr( model, "residues" ): for r in model.residues: key = r.resname - if atom_types.has_key(key): + if key in atom_types: dic = atom_types[key] for atom in r.atoms: name = atom.long_name.strip() - if dic.has_key(name): + if name in dic: atom.atype = dic[name]['type'] atom.hyb = dic[name]['hyb'] else: #elif isinstance(model,pmx.Molecule): key = model.resname - if atom_types.has_key(key): + if key in atom_types: dic = atom_types[key] for atom in model.atoms: name = atom.long_name.strip() - if dic.has_key(name): + if name in dic: atom.atype = dic[name]['type'] atom.hyb = dic[name]['hyb'] - + # check if we got all # and do generic dic = atom_types['GENERIC'] for atom in model.atoms: if atom.atype == '': - if dic.has_key(atom.symbol): + if atom.symbol in dic: atom.atype = dic[atom.symbol]['type'] if verbose: - print 'Using generic atom type for atom %d-%s/%d-%s (%s)' %\ - (atom.id, atom.name, atom.resnr, atom.resname, atom.long_name) + print('Using generic atom type for atom %d-%s/%d-%s (%s)' %\ + (atom.id, atom.name, atom.resnr, atom.resname, atom.long_name)) else: - print 'Could not assign atom type to atom %d-%s/%d-%s' %\ - (atom.id, atom.name, atom.resnr, atom.resname) - - + print('Could not assign atom type to atom %d-%s/%d-%s' %\ + (atom.id, atom.name, atom.resnr, atom.resname)) + + def assign_radii(model): try: lst = open('Atomradii.dat').readlines() @@ -136,7 +136,7 @@ def assign_radii(model): lst = kickOutComments(lst,';') tps = readSection(lst,'[ TYPES ]','[') tps = parseList('sff',tps) - types = map(lambda a: a[0], tps) + types = [a[0] for a in tps] dic = {} pdic = {} for i, line in enumerate(tps): @@ -152,7 +152,7 @@ def assign_radii(model): comb = parseList('ssf',comb) comb14 = readSection(lst,'[ 14_COMBINATIONS ]','[') comb14 = parseList('ssf',comb14) - + size = len(tps) table = zeros((size,size)) table14 = zeros((size,size)) @@ -171,9 +171,6 @@ def assign_radii(model): idx2 = types.index(c[1]) table14[idx1][idx2] = c[2] table14[idx2][idx1] = c[2] - + model.vdwtab = table model.vdw14tab = table14 - - - diff --git a/pmx/xdrfile.py b/pmx/xdrfile.py index d2bb9a5d..858f0a5e 100644 --- a/pmx/xdrfile.py +++ b/pmx/xdrfile.py @@ -1,24 +1,24 @@ # -*- mode: python; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- -# +# # $Id$ -# +# # Copyright (c) Erik Lindahl, David van der Spoel 2003-2007. # Coordinate compression (c) by Frans van Hoesel. # Python wrapper (c) by Roland Schulz -# +# # IN contrast to the rest of Gromacs, XDRFILE is distributed under the # BSD license, so you can use it any way you wish, including closed source: -# +# # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -26,7 +26,7 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. -# +# # Adapted by Daniel Seeliger for use in the pmx package (Aug 2015) # import numpy as np @@ -42,9 +42,9 @@ class Frame: #variables #x: rvec*natoms / numpy array if installed #box DIM*DIM - #step - #time - #prec + #step + #time + #prec #lam: lambda def __init__(self,n,mode,x=None,box=None,units=None,v=None,f=None): @@ -55,7 +55,7 @@ def __init__(self,n,mode,x=None,box=None,units=None,v=None,f=None): scale = 1.0 if units == 'A': scale=0.1 - self.x=((c_float*3)*n)() + self.x=((c_float*3)*n)() i=0 for a in range(0,self.natoms): for dim in range(0,3): @@ -64,7 +64,7 @@ def __init__(self,n,mode,x=None,box=None,units=None,v=None,f=None): elif mode&mNumPy and mode!=out_mode: self.x=empty((n,3),dtype=float32) else: - self.x=((c_float*3)*n)() + self.x=((c_float*3)*n)() # dummy v and f for .trr self.v_size = c_size_t(0) @@ -117,17 +117,17 @@ def get_step(self): return self.step def get_prec(self): return self.prec - def get_box(self, mode='std'): - if mode == 'std': - box = [[0.,0.,0.], - [0.,0.,0.], - [0.,0.,0.]] - elif mode == 'numpy': - box = np.zeros((3,3)) - for i in range(3): - for k in range(3): - box[i][k] = self.box[i][k] - return box + def get_box(self, mode='std'): + if mode == 'std': + box = [[0.,0.,0.], + [0.,0.,0.], + [0.,0.,0.]] + elif mode == 'numpy': + box = np.zeros((3,3)) + for i in range(3): + for k in range(3): + box[i][k] = self.box[i][k] + return box @@ -140,28 +140,28 @@ def __str__(self): class XDRFile: - exdrOK, exdrHEADER, exdrSTRING, exdrDOUBLE, exdrINT, exdrFLOAT, exdrUINT, exdr3DX, exdrCLOSE, exdrMAGIC, exdrNOMEM, exdrENDOFFILE, exdrNR = range(13) + exdrOK, exdrHEADER, exdrSTRING, exdrDOUBLE, exdrINT, exdrFLOAT, exdrUINT, exdr3DX, exdrCLOSE, exdrMAGIC, exdrNOMEM, exdrENDOFFILE, exdrNR = list(range(13)) # def __init__(self,fn,mode="Auto",ft="Auto",atomNum=False): if mode=="NumPy": - self.mode=mNumPy - try: - empty - except NameError: - raise IOError("NumPy selected but not correctly installed") + self.mode=mNumPy + try: + empty + except NameError: + raise IOError("NumPy selected but not correctly installed") elif mode=="Std": - self.mode=0 + self.mode=0 elif mode=="Auto": - self.mode=auto_mode + self.mode=auto_mode elif mode=='Out': - self.mode=out_mode - else: - raise IOError("unsupported mode") - + self.mode=out_mode + else: + raise IOError("unsupported mode") + if ft=="Auto": - ft = os.path.splitext(fn)[1][1:] - + ft = os.path.splitext(fn)[1][1:] + if self.mode!=out_mode: if ft=="trr": self.mode|=mTrr @@ -169,27 +169,27 @@ def __init__(self,fn,mode="Auto",ft="Auto",atomNum=False): pass else: raise IOError("Only xtc and trr supported") - + #load libxdrfil - try: - p = os.path.join(os.path.dirname(__file__),'_xdrio.so') - self.xdr=cdll.LoadLibrary(p) + try: + p = os.path.join(os.path.dirname(__file__),'_xdrio.cpython-310-x86_64-linux-gnu.so') + self.xdr=cdll.LoadLibrary(p) except: - raise IOError("_xdrio.so can't be loaded") - - + raise IOError("_xdrio.so can't be loaded") + + #open file if self.mode==out_mode: self.xd = self.xdr.xdrfile_open(fn,"w") else: self.xd = self.xdr.xdrfile_open(fn,"r") if not self.xd: raise IOError("Cannot open file: '%s'"%fn) - + #read natoms natoms=c_int() if self.mode==out_mode: if atomNum==False: - raise StandardError("To write an .xtc need to provide the number of atoms") + raise Exception("To write an .xtc need to provide the number of atoms") self.natoms = atomNum else: if self.mode&mTrr: @@ -198,7 +198,7 @@ def __init__(self,fn,mode="Auto",ft="Auto",atomNum=False): r=self.xdr.read_xtc_natoms(fn,byref(natoms)) if r!=self.exdrOK: raise IOError("Error reading: '%s'"%fn) self.natoms=natoms.value - + #for NumPy define argtypes - ndpointer is not automatically converted to POINTER(c_float) #alternative of ctypes.data_as(POINTER(c_float)) requires two version for numpy and c_float array if self.mode&mNumPy and self.mode!=out_mode: @@ -218,7 +218,7 @@ def write_xtc_frame( self, step=0, time=0.0, prec=1000.0, lam=0.0, box=False, x= result = self.xdr.write_trr(self.xd,self.natoms,step,time,lam,f.box,f.x,f.v,f.f) else: result = self.xdr.write_xtc(self.xd,self.natoms,step,time,f.box,f.x,prec) - + def __iter__(self): f = Frame(self.natoms,self.mode) #temporary c_type variables (frame variables are python type) @@ -235,15 +235,14 @@ def __iter__(self): else: result = self.xdr.read_trr(self.xd,self.natoms,byref(step),byref(time),byref(lam),f.box,f.x,None,None) #TODO: make v,f possible f.lam=lam.value - + #check return value if result==self.exdrENDOFFILE: break - if result==self.exdrINT and self.mode&mTrr: - break #TODO: dirty hack. read_trr return exdrINT not exdrENDOFFILE + if result==self.exdrINT and self.mode&mTrr: + break #TODO: dirty hack. read_trr return exdrINT not exdrENDOFFILE if result!=self.exdrOK: raise IOError("Error reading xdr file") - - #convert c_type to python + + #convert c_type to python f.step=step.value f.time=time.value yield f - diff --git a/pmx/xtc.py b/pmx/xtc.py index 64c7dee0..4dec8158 100644 --- a/pmx/xtc.py +++ b/pmx/xtc.py @@ -28,7 +28,8 @@ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # ---------------------------------------------------------------------- -import sys, os, xdrfile +import sys, os +from . import xdrfile class Trajectory(xdrfile.XDRFile): @@ -40,9 +41,3 @@ def __init__(self, filename, **kwargs): def get_natoms(self): return self.natoms - - - - - - diff --git a/setup.py b/setup.py index 542170de..8e6b30b8 100644 --- a/setup.py +++ b/setup.py @@ -82,7 +82,7 @@ def readme(): include_package_data=True, zip_safe=False, ext_modules=extensions, - python_requires=">=2.7, <3", + python_requires=">=3.0", install_requires=['numpy>=1.14', 'scipy>=1.1', 'matplotlib>=2.2'], entry_points={'console_scripts': ['pmx = pmx.scripts.cli:entry_point']} ) diff --git a/versioneer.py b/versioneer.py index 64fea1c8..d3e699c3 100644 --- a/versioneer.py +++ b/versioneer.py @@ -276,11 +276,11 @@ """ -from __future__ import print_function + try: import configparser except ImportError: - import ConfigParser as configparser + import configparser as configparser import errno import json import os