Mercurial > repos > guerler > springsuite
comparison spring_package/Modeller.py @ 39:172398348efd draft
"planemo upload commit 26b4018c88041ee0ca7c2976e0a012015173d7b6-dirty"
| author | guerler |
|---|---|
| date | Fri, 22 Jan 2021 15:50:27 +0000 |
| parents | |
| children | 06337927c198 |
comparison
equal
deleted
inserted
replaced
| 38:80a4b98121b6 | 39:172398348efd |
|---|---|
| 1 import subprocess | |
| 2 from os import mkdir | |
| 3 from os.path import basename, isdir | |
| 4 | |
| 5 from spring_package.Alignment import Alignment | |
| 6 from spring_package.DBKit import DBKit | |
| 7 from spring_package.Energy import Energy | |
| 8 from spring_package.Molecule import Molecule | |
| 9 from spring_package.Utilities import getChain, getCrossReference, getName, getTemplates | |
| 10 | |
| 11 | |
| 12 def createPDB(identifier, pdbDatabase, outputName): | |
| 13 pdb = getName(identifier) | |
| 14 pdbDatabaseId = "%s.pdb" % pdb | |
| 15 return pdbDatabase.createFile(pdbDatabaseId, outputName) | |
| 16 | |
| 17 | |
| 18 def createMonomer(resultFile, identifier, pdbDatabase, outputName): | |
| 19 print("Building model with: %s." % identifier) | |
| 20 if not createPDB(identifier, pdbDatabase, outputName): | |
| 21 return False | |
| 22 template = Molecule(outputName) | |
| 23 pdbChain = getChain(identifier) | |
| 24 if pdbChain not in template.calpha: | |
| 25 print("Chain not found in template [%s]" % pdbChain) | |
| 26 return False | |
| 27 chain = template.calpha[pdbChain] | |
| 28 alignment = Alignment(resultFile) | |
| 29 alignment.createModel(chain) | |
| 30 template.saveChain(pdbChain, outputName) | |
| 31 try: | |
| 32 subprocess.run(["pulchra", outputName], check=True) | |
| 33 except subprocess.CalledProcessError as e: | |
| 34 raise Exception(str(e)) | |
| 35 return True | |
| 36 | |
| 37 | |
| 38 def TMalign(fileA, fileB, tmName="temp/tmalign"): | |
| 39 try: | |
| 40 tmResult = open("%s.out" % tmName, "w") | |
| 41 subprocess.run(["tmalign", fileA, fileB, "-m", "%s.mat" % tmName], check=True, stdout=tmResult) | |
| 42 tmResult.close() | |
| 43 except subprocess.CalledProcessError as e: | |
| 44 raise Exception(str(e)) | |
| 45 rotmat = list() | |
| 46 with open("%s.mat" % tmName) as file: | |
| 47 line = next(file) | |
| 48 line = next(file) | |
| 49 for i in range(3): | |
| 50 line = next(file) | |
| 51 rotmatLine = line.split() | |
| 52 rotmatLine = list(map(lambda x: float(x), rotmatLine)) | |
| 53 rotmatLine = [rotmatLine[2], rotmatLine[3], rotmatLine[4], rotmatLine[1]] | |
| 54 rotmat.append(rotmatLine) | |
| 55 with open("%s.out" % tmName) as file: | |
| 56 for i in range(18): | |
| 57 line = next(file) | |
| 58 try: | |
| 59 tmscore = float(line[9:17]) | |
| 60 line = next(file) | |
| 61 tmscore = max(tmscore, float(line[9:17])) | |
| 62 except Exception: | |
| 63 raise Exception("TMalign::Failed to retrieve TMscore.") | |
| 64 molecule = Molecule(fileA) | |
| 65 for atom in molecule.atoms: | |
| 66 molecule.applyMatrix(atom, rotmat) | |
| 67 return tmscore, molecule | |
| 68 | |
| 69 | |
| 70 def TMalignAlignment(bioMolecule, templateChain, tmName="temp/tmalign"): | |
| 71 aligned = list() | |
| 72 with open("%s.out" % tmName) as file: | |
| 73 for i in range(23): | |
| 74 line = next(file) | |
| 75 try: | |
| 76 modelAlign = line | |
| 77 line = next(file) | |
| 78 alignment = line | |
| 79 line = next(file) | |
| 80 templateAlign = line | |
| 81 except Exception: | |
| 82 raise Exception("TMalign::Failed to retrieve TMalign results.") | |
| 83 templateResidues = sorted(bioMolecule.calpha[templateChain].values(), key=lambda item: item["residueNumber"]) | |
| 84 templateIndex = 0 | |
| 85 for i in range(len(alignment)): | |
| 86 t = templateAlign[i] | |
| 87 if alignment[i] == ":": | |
| 88 templateResidue = templateResidues[templateIndex] | |
| 89 templateResidue["alignedResidue"] = modelAlign[i] | |
| 90 aligned.append(templateResidue) | |
| 91 if t != "-": | |
| 92 templateIndex = templateIndex + 1 | |
| 93 return aligned | |
| 94 | |
| 95 | |
| 96 def getFrameworks(aTemplates, bTemplates, crossReference, minScore, maxTries): | |
| 97 templateHits = list() | |
| 98 for aTemplate in aTemplates: | |
| 99 if aTemplate in crossReference: | |
| 100 partners = crossReference[aTemplate]["partners"] | |
| 101 templates = crossReference[aTemplate]["templates"] | |
| 102 for pIndex in range(len(partners)): | |
| 103 pTemplate = partners[pIndex] | |
| 104 templatePair = templates[pIndex] | |
| 105 if pTemplate in bTemplates: | |
| 106 minZ = min(aTemplates[aTemplate], bTemplates[pTemplate]) | |
| 107 templateHits.append(dict(templatePair=templatePair, score=minZ)) | |
| 108 templateList = sorted(templateHits, key=lambda item: item["score"], reverse=True) | |
| 109 print("Found %d templates." % len(templateList)) | |
| 110 for templateHit in templateList: | |
| 111 if templateHit["score"] < minScore or maxTries == 0: | |
| 112 break | |
| 113 maxTries = maxTries - 1 | |
| 114 yield templateHit["templatePair"] | |
| 115 | |
| 116 | |
| 117 def createModel(args): | |
| 118 print("SPRING - Complex Model Creation") | |
| 119 aName = basename(args.a_hhr) | |
| 120 bName = basename(args.b_hhr) | |
| 121 print("Sequence A: %s" % aName) | |
| 122 print("Sequence B: %s" % bName) | |
| 123 aTop, aTemplates = getTemplates(args.a_hhr) | |
| 124 bTop, bTemplates = getTemplates(args.b_hhr) | |
| 125 if not isdir("temp"): | |
| 126 mkdir("temp") | |
| 127 outputName = args.output | |
| 128 pdbDatabase = DBKit(args.index, args.database) | |
| 129 crossReference = getCrossReference(args.cross) | |
| 130 interfaceEnergy = Energy() | |
| 131 if not createMonomer(args.a_hhr, aTop, pdbDatabase, "temp/monomerA.pdb"): | |
| 132 print("Warning: Failed to determine monomer model for %s." % args.a_hhr) | |
| 133 return False | |
| 134 if not createMonomer(args.b_hhr, bTop, pdbDatabase, "temp/monomerB.pdb"): | |
| 135 print("Warning: Failed to determine monomer model for %s." % args.b_hhr) | |
| 136 return False | |
| 137 maxScore = -9999 | |
| 138 maxInfo = None | |
| 139 minScore = float(args.minscore) | |
| 140 maxTries = int(args.maxtries) | |
| 141 for [aTemplate, bTemplate] in getFrameworks(aTemplates, bTemplates, crossReference, minScore=minScore, maxTries=maxTries): | |
| 142 print("Evaluating Complex Template: %s." % aTemplate) | |
| 143 templateFile = "temp/template.pdb" | |
| 144 createPDB(aTemplate, pdbDatabase, templateFile) | |
| 145 templateMolecule = Molecule(templateFile) | |
| 146 aTemplateChain = getChain(aTemplate) | |
| 147 bTemplateChain = getChain(bTemplate) | |
| 148 if aTemplateChain == bTemplateChain: | |
| 149 bTemplateChain = "%s_0" % bTemplateChain | |
| 150 print("Evaluating chain %s and %s..." % (aTemplate, bTemplate)) | |
| 151 biomolFound = False | |
| 152 for biomolNumber in templateMolecule.biomol: | |
| 153 bioMolecule = templateMolecule.createUnit(biomolNumber) | |
| 154 if (len(bioMolecule.calpha.keys()) > 1 | |
| 155 and aTemplateChain in bioMolecule.calpha | |
| 156 and bTemplateChain in bioMolecule.calpha): | |
| 157 print("Evaluating biomolecule %i..." % biomolNumber) | |
| 158 bioMolecule.saveChain(aTemplateChain, "temp/template_0.pdb") | |
| 159 bioMolecule.saveChain(bTemplateChain, "temp/template_1.pdb") | |
| 160 try: | |
| 161 coreScore, coreMolecule = TMalign("temp/monomerA.rebuilt.pdb", "temp/template_0.pdb") | |
| 162 coreAligned = TMalignAlignment(bioMolecule, aTemplateChain) | |
| 163 partnerScore, partnerMolecule = TMalign("temp/monomerB.rebuilt.pdb", "temp/template_1.pdb") | |
| 164 partnerAligned = TMalignAlignment(bioMolecule, bTemplateChain) | |
| 165 except Exception as e: | |
| 166 print("Warning: Failed TMalign [%s]." % bTemplateChain) | |
| 167 print(str(e)) | |
| 168 continue | |
| 169 biomolFound = True | |
| 170 tmscore = min(coreScore, partnerScore) | |
| 171 print(" tmscore:\t%5.2f" % tmscore) | |
| 172 energy = -interfaceEnergy.get(coreAligned, partnerAligned) | |
| 173 print(" energy:\t%5.2f" % energy) | |
| 174 clashes = interfaceEnergy.getClashes(coreMolecule, partnerMolecule) | |
| 175 print(" clashes:\t%5.2f" % clashes) | |
| 176 springscore = tmscore + energy * args.wenergy | |
| 177 print(" springscore:\t%5.2f" % springscore) | |
| 178 if springscore > maxScore and clashes < args.maxclashes: | |
| 179 maxScore = springscore | |
| 180 maxInfo = dict(springscore=springscore, tmscore=tmscore, energy=energy, clashes=clashes) | |
| 181 coreMolecule.save(outputName, chainName="0") | |
| 182 partnerMolecule.save(outputName, chainName="1", append=True) | |
| 183 if args.showtemplate == "true": | |
| 184 bioMolecule.save(outputName, append=True) | |
| 185 if biomolFound: | |
| 186 break | |
| 187 if maxInfo is not None: | |
| 188 print("Final Model:") | |
| 189 for key in maxInfo: | |
| 190 print(" %s:\t%5.2f" % (key, maxInfo[key])) | |
| 191 print("Completed.") | |
| 192 else: | |
| 193 print("Warning: Failed to determine model.") | |
| 194 return maxInfo |
