From 0fd51a6955fbb3baa98ac1db6c7cba12d3aed4a3 Mon Sep 17 00:00:00 2001 From: schenc3 Date: Tue, 30 Jun 2015 14:23:58 -0400 Subject: [PATCH] FlexPepDock --- InteractiveROSETTA/linux_install.sh | 9 +- .../scripts/advresiduecreator.py | 1 + InteractiveROSETTA/scripts/compmodel.py | 45 +- InteractiveROSETTA/scripts/daemon.py | 196 ++- InteractiveROSETTA/scripts/docking.py | 21 + InteractiveROSETTA/scripts/flexpepdock.py | 1138 +++++------------ InteractiveROSETTA/scripts/kic.py | 176 ++- InteractiveROSETTA/scripts/pointmutations.py | 7 + InteractiveROSETTA/scripts/protocols.py | 8 + InteractiveROSETTA/scripts/residuecreator.py | 1 + InteractiveROSETTA/scripts/selection.py | 2 +- InteractiveROSETTA/scripts/sequence.py | 65 +- InteractiveROSETTA/scripts/surfaces.py | 29 +- .../server/cgi-bin/jobupload.cgi | 3 +- InteractiveROSETTA/server/daemon_server.py | 183 ++- InteractiveROSETTA/server/rosetta_submit.py | 632 ++++++--- 16 files changed, 1289 insertions(+), 1227 deletions(-) diff --git a/InteractiveROSETTA/linux_install.sh b/InteractiveROSETTA/linux_install.sh index dd10bf6..ba3a0e3 100644 --- a/InteractiveROSETTA/linux_install.sh +++ b/InteractiveROSETTA/linux_install.sh @@ -28,10 +28,11 @@ cd "$SCRIPTDIR" # Have the user unpackage PyRosetta before doing anything else echo "Searching for PyRosetta installation..." read -p "Enter a directory to search (default: "$SEARCHDIR"): " input -if [ $input != "" ]; then +if [ $input ]; then SEARCHDIR=$input fi NEWROSETTA=`find $SEARCHDIR -name SetPyRosettaEnvironment* 2> /dev/null | head -n 1 | awk -F "/SetPyRosetta" '{print $1}' ` +echo "Looking for PyRosetta in "$NEWROSETTA if [ $NEWROSETTA != "" ]; then # This is obnoxious...there is a colon in the Ubuntu PyRosetta directory name # and it messes up : delimited paths, so create an appropriate symlink @@ -98,7 +99,11 @@ echo "Installing poster..." sudo easy_install -q poster echo "Installing requests..." sudo easy_install -q requests -echo "Installing OpenBabel..." +echo "Installing pyperclip..." +sudo easy_install -q pyperclip +echo "Downloading OpenBabel..." +rm -f openbabel-2.3.1.tar.gz +$PMGR"wget" if [[ $ROSETTA_VER == "Ubuntu" ]]; then $PMGR"python-openbabel" else diff --git a/InteractiveROSETTA/scripts/advresiduecreator.py b/InteractiveROSETTA/scripts/advresiduecreator.py index b6d07d3..a8c5d8c 100644 --- a/InteractiveROSETTA/scripts/advresiduecreator.py +++ b/InteractiveROSETTA/scripts/advresiduecreator.py @@ -651,6 +651,7 @@ def addToDB(self, event): self.resMenu.Clear() self.resMenu.AppendItems(self.unrecognized_types.keys()) self.removeMenu.Append(self.selectedType) + self.cmd.remove("params") def removeParams(self, event): # Take the indicated parameters file out of the database diff --git a/InteractiveROSETTA/scripts/compmodel.py b/InteractiveROSETTA/scripts/compmodel.py index c8fb957..540b368 100644 --- a/InteractiveROSETTA/scripts/compmodel.py +++ b/InteractiveROSETTA/scripts/compmodel.py @@ -44,57 +44,16 @@ def __init__(self, parent, W, H): self.HelpBtn.SetToolTipString("Display the help file for this window") if (platform.system() == "Windows"): - self.lblInst = wx.StaticText(self, -1, "Model a structure ab initio using an existing\nstructure as a template.\nFirst generate fragment files using Robetta.\nRegistration with Robetta is required to do this.", (0, 45), (320, 25), wx.ALIGN_CENTRE) + self.lblInst = wx.StaticText(self, -1, "Model a structure ab initio using an existing\nstructure as a template.", (0, 45), (320, 25), wx.ALIGN_CENTRE) self.lblInst.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.NORMAL)) elif (platform.system() == "Darwin"): self.lblInst = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblInstCompModel.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, 45), size=(320, 80)) else: - self.lblInst = wx.StaticText(self, -1, "Model a structure ab initio using an existing\nstructure as a template.\nFirst generate fragment files using Robetta.\nRegistration with Robetta is required to do this.", (5, 45), style=wx.ALIGN_CENTRE) + self.lblInst = wx.StaticText(self, -1, "Model a structure ab initio using an existing\nstructure as a template.", (5, 45), style=wx.ALIGN_CENTRE) self.lblInst.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.NORMAL)) resizeTextControlForUNIX(self.lblInst, 0, self.GetSize()[0]-20) self.lblInst.SetForegroundColour("#FFFFFF") - if (platform.system() == "Windows"): - self.lblVisit = wx.StaticText(self, -1, "Visit Robetta", (0, 130), (155, 20), wx.ALIGN_CENTRE) - self.lblVisit.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) - elif (platform.system() == "Darwin"): - self.lblVisit = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblVisit.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, 130), size=(155, 20)) - else: - self.lblVisit = wx.StaticText(self, -1, "Visit Robetta", (0, 130), style=wx.ALIGN_CENTRE) - self.lblVisit.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) - resizeTextControlForUNIX(self.lblVisit, 0, 155) - self.lblVisit.SetForegroundColour("#FFFFFF") - if (platform.system() == "Darwin"): - self.btnFragGen = wx.BitmapButton(self, id=-1, bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnFragments.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(175, 125), size=(120, 25)) - else: - self.btnFragGen = wx.Button(self, id=-1, label="Get Fragments", pos=(175, 125), size=(120, 25)) - self.btnFragGen.SetForegroundColour("#000000") - self.btnFragGen.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.BOLD)) - self.btnFragGen.Bind(wx.EVT_BUTTON, self.fragGen) - self.btnFragGen.SetToolTipString("Visit Robetta to generate fragment files") - - if (platform.system() == "Windows"): - self.lblJobID = wx.StaticText(self, -1, "Job ID:", (0, 163), (100, 20), wx.ALIGN_CENTRE) - self.lblJobID.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) - elif (platform.system() == "Darwin"): - self.lblJobID = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblJobID.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, 163), size=(100, 20)) - else: - self.lblJobID = wx.StaticText(self, -1, "Job ID:", (0, 163), style=wx.ALIGN_CENTRE) - self.lblJobID.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) - resizeTextControlForUNIX(self.lblJobID, 0, 100) - self.lblJobID.SetForegroundColour("#FFFFFF") - self.txtJobID = wx.TextCtrl(self, -1, pos=(110, 160), size=(100, 25)) - self.txtJobID.SetValue("") - self.txtJobID.SetToolTipString("Job ID for submitted Robetta fragment job.") - if (platform.system() == "Darwin"): - self.btnWatch = wx.BitmapButton(self, id=-1, bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnWatch.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(220, 160), size=(100, 25)) - else: - self.btnWatch = wx.Button(self, id=-1, label="Watch", pos=(220, 160), size=(100, 25)) - self.btnWatch.SetForegroundColour("#000000") - self.btnWatch.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.BOLD)) - self.btnWatch.Bind(wx.EVT_BUTTON, self.jobWatch) - self.btnWatch.SetToolTipString("Start automatically watching for the specified job ID to complete") - if (platform.system() == "Windows"): self.lblModel = wx.StaticText(self, -1, "Templates", (0, 190), (155, 20), wx.ALIGN_CENTRE) self.lblModel.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) diff --git a/InteractiveROSETTA/scripts/daemon.py b/InteractiveROSETTA/scripts/daemon.py index 380e513..1e7cbf1 100644 --- a/InteractiveROSETTA/scripts/daemon.py +++ b/InteractiveROSETTA/scripts/daemon.py @@ -705,7 +705,36 @@ def doScore(): total_E = scorefxn(pose) # Dump the output outputpdb = pdbfile.split(".pdb")[0] + "_S.pdb" + # Save atomic charge information in the segment identifier fields (columns 73-76 in PDB) + # PyMOL reads that as the "segl" field + info = pose.pdb_info() + charges = {} + for ires in range(1, pose.n_residue()+1): + for iatom in range(1, len(pose.residue(ires).atoms())+1): + pc = pose.residue(ires).atomic_charge(iatom) + pc = round(pc * 4.0) + if (pc < -4): + pc = -4 + elif (pc > 4): + pc = 4 + charges[str(info.number(ires)) + pose.residue(ires).atom_name(iatom)] = int(pc) pose.dump_pdb(outputpdb) + # Now manually insert the charges + fin = open(outputpdb, "r") + data = [] + for aline in fin: + data.append(aline) + fin.close() + fout = open(outputpdb, "w") + for aline in data: + if (aline.startswith("ATOM") or aline.startswith("HETATM")): + pc = charges[aline[22:26].strip() + aline[12:16]] + if (pc < 0): + aline = aline[0:78] + "%1i-" % (pc * -1) + aline[80:] + else: + aline = aline[0:78] + "%1i+" % pc + aline[80:] + fout.write(aline) + fout.close() # Now write the output information for the main GUI f.write("OUTPUT\t" + outputpdb + "\n") f.write("TOTAL_E\t" + str(total_E) + "\n") @@ -714,7 +743,6 @@ def doScore(): for scoretype in nonzero_scoretypes: f.write("\t" + str(scoretype)) f.write("\n") - info = pose.pdb_info() for res in range(1, pose.n_residue()+1): # Skip HETATMs/NCAAs if (not(pose.residue(res).name1() in "ACDEFGHIKLMNPQRSTVWY")): @@ -906,6 +934,7 @@ def doKIC(stage="Coarse"): raise Exception("ERROR: The file \"finekicinput\" is missing!") # Get the pdbfile, resfile, and scorefxn from the input file pivotOffset = 0 + loopdata = [] for aline in f: if (aline[0:7] == "PDBFILE"): # But for the fine grained step the pose comes from repacked.pdb @@ -922,6 +951,9 @@ def doKIC(stage="Coarse"): loopEnd = int(aline.split("\t")[1]) elif (aline[0:5] == "PIVOT"): pivotOffset = int(aline.split("\t")[1]) + elif (aline[0:4] == "LOOP"): + # Save the information in a list that we will iterate through later + loopdata.append(aline.strip().split("\t")[1:]) elif (aline[0:7] == "NSTRUCT"): nstruct = int(aline.split("\t")[1]) elif (aline[0:7] == "PERTURB"): @@ -937,36 +969,9 @@ def doKIC(stage="Coarse"): raise Exception("ERROR: The scoring function weights could not be initialized!") if (stage == "Coarse"): pose = pose_from_pdb(pdbfile) - if (loopType == "DE NOVO"): - if (stage == "Coarse"): - # Since this is a new sequence being added, we first have to delete all the residues - # between the beginning and ending points - for ires in range(loopEnd-1, loopBegin, -1): - pose.delete_polymer_residue(ires) - # Now we have to add the sequence using our nifty little "rsd_factory" pose - # The residues will have coordinates in weird places but it doesn't matter because - # KIC fixes that and puts them in the right place; they don't need to start out anywhere - # near being right - try: - rsd_factory = pose_from_pdb("data/residues.pdb") - except: - raise Exception("ERROR: The file \"data/residues.pdb\" is missing!") - offset = 0 - for AA in sequence.strip(): - indx = "ACDEFGHIKLMNPQRSTVWY".find(AA) + 2 - pose.append_polymer_residue_after_seqpos(Residue(rsd_factory.residue(indx)), loopBegin+offset, True) - offset = offset + 1 - # Now maybe the sequence is longer than what was originally the length of the sequence - # between start and end, so we need to recalculate the loop end - loopEnd = loopBegin + len(sequence.strip()) + 1 - elif (loopType == "REFINE"): - # Here we only want to do high resolution modeling - stage = "Fine" - nstruct = 1 - # We have to take the HETATMs out otherwise it will crash the centroid mover - # We could try to make centroid params files, but it seems that they sometimes cause Rosetta to seg fault, which we cannot have - # Later we'll put them back in - if (stage == "Coarse"): + # We have to take the HETATMs out otherwise it will crash the centroid mover + # We could try to make centroid params files, but it seems that they sometimes cause Rosetta to seg fault, which we cannot have + # Later we'll put them back in HETATMs = [] HETATM_indx = [] info = pose.pdb_info() @@ -976,10 +981,14 @@ def doKIC(stage="Coarse"): HETATMs.append([i, Residue(pose.residue(i))]) else: HETATM_indx.append((info.chain(i), info.number(i))) - if (i < loopBegin): - loopBegin = loopBegin -1 - if (i < loopEnd): - loopEnd = loopEnd -1 + # Taking these residues out might change where the loop anchors are + for j in range(0, len(loopdata)): + if (i < int(loopdata[j][2])): + loopdata[j][2] = int(loopdata[j][2]) -1 + if (i < int(loopdata[j][3])): + loopdata[j][3] = int(loopdata[j][3]) -1 + if (i < int(loopdata[j][4])): + loopdata[j][4] = int(loopdata[j][4]) -1 if (i == 1): pose.replace_residue(1, pose.residue(2), False) pose.delete_polymer_residue(2) @@ -994,18 +1003,59 @@ def doKIC(stage="Coarse"): if ((chain, seqpos) in HETATM_indx): HETATM_lines.append(aline.strip()) f.close() - if (loopType == "DE NOVO" and stage == "Coarse"): - # This has to be hard-coded, because the loop is not actually there until coarse modeling happens so there's no pivot point - # other than the loop anchor residues - cutpoint = loopEnd - else: - cutpoint = loopBegin + pivotOffset - loop = Loop(loopBegin, loopEnd, cutpoint, 0, 1) - loops = Loops() - loops.add_loop(loop) + loops = [] + for [loopType, sequence, begin, pivot, end] in loopdata: + loopBegin = int(begin) + pivot = int(pivot) + loopEnd = int(end) + if (loopType == "DE NOVO"): + if (stage == "Coarse"): + # Since this is a new sequence being added, we first have to delete all the residues + # between the beginning and ending points + oldlen = 0 + for ires in range(loopEnd-1, loopBegin, -1): + pose.delete_polymer_residue(ires) + oldlen += 1 + # Now we have to add the sequence using our nifty little "rsd_factory" pose + # The residues will have coordinates in weird places but it doesn't matter because + # KIC fixes that and puts them in the right place; they don't need to start out anywhere + # near being right + try: + rsd_factory = pose_from_pdb("data/residues.pdb") + except: + raise Exception("ERROR: The file \"data/residues.pdb\" is missing!") + offset = 0 + for AA in sequence.strip(): + indx = "ACDEFGHIKLMNPQRSTVWY".find(AA) + 2 + pose.append_polymer_residue_after_seqpos(Residue(rsd_factory.residue(indx)), loopBegin+offset, True) + offset = offset + 1 + # Now we have to update the begin and end points of the other loops if necessary + for j in range(0, len(loopdata)): + if (loopBegin < int(loopdata[j][2])): + loopdata[j][2] = int(loopdata[j][2]) + len(sequence) - oldlen + if (loopBegin < int(loopdata[j][3])): + loopdata[j][3] = int(loopdata[j][3]) + len(sequence) - oldlen + if (loopBegin < int(loopdata[j][4])): + loopdata[j][4] = int(loopdata[j][4]) + len(sequence) - oldlen + # Now maybe the sequence is longer than what was originally the length of the sequence + # between start and end, so we need to recalculate the loop end + loopEnd = loopBegin + len(sequence.strip()) + 1 + #elif (loopType == "REFINE"): + # Here we only want to do high resolution modeling + # stage = "Fine" + # nstruct = 1 + if (loopType == "DE NOVO" and stage == "Coarse"): + # This has to be hard-coded, because the loop is not actually there until coarse modeling happens so there's no pivot point + # other than the loop anchor residues + cutpoint = loopEnd + else: + cutpoint = pivot + if (loopType == "REFINE"): + loop = Loop(loopBegin, loopEnd, cutpoint, 0, 0) + else: + loop = Loop(loopBegin, loopEnd, cutpoint, 0, 1) + loops.append(loop) if (stage == "Coarse"): - add_single_cutpoint_variant(pose, loop) - set_single_loop_fold_tree(pose, loop) # Low res KIC for decoy in range(0, nstruct): sw = SwitchResidueTypeSetMover("centroid") @@ -1013,12 +1063,17 @@ def doKIC(stage="Coarse"): sw.apply(pose) except: raise Exception("ERROR: The PDB could not be converted to centroid mode!") - kic_perturb = LoopMover_Perturb_KIC(loops) - kic_perturb.set_max_kic_build_attempts(120) - try: - kic_perturb.apply(pose) - except: - raise Exception("ERROR: The coarse KIC perturber failed!") + for loop in loops: + loops_set = Loops() + loops_set.add_loop(loop) + add_single_cutpoint_variant(pose, loop) + set_single_loop_fold_tree(pose, loop) + kic_perturb = LoopMover_Perturb_KIC(loops_set) + kic_perturb.set_max_kic_build_attempts(120) + try: + kic_perturb.apply(pose) + except: + raise Exception("ERROR: The coarse KIC perturber failed!") if (perturbType == "Perturb Only, Centroid"): outputpdb = pdbfile.split(".pdb")[0] + "_K.pdb" pose.dump_pdb(outputpdb) @@ -1081,19 +1136,37 @@ def doKIC(stage="Coarse"): for aline in HETATM_lines: f.write(aline + "\n") f.close() + # Now we have to rewrite the input file for refined mode, since if we added or deleted + # sequence the loop beginning and ending points may have changed + fin = open("coarsekicinput", "r") + filedata = [] + for aline in fin: + if (aline[0:5] == "LOOP\t"): + continue + filedata.append(aline) + fin.close() + fout = open("coarsekicinput", "w") + for aline in filedata: + fout.write(aline) + for [loopType, sequence, begin, pivot, end] in loopdata: + fout.write("LOOP\t" + loopType + "\t" + sequence.strip() + "\t" + str(begin) + "\t" + str(pivot) + "\t" + str(end) + "\n") + fout.close() else: for decoy in range(0, nstruct): if (loopType == "REFINE"): pose = pose_from_pdb(pdbfile) else: pose = pose_from_pdb("repacked_" + str(decoy) + ".pdb") - add_single_cutpoint_variant(pose, loop) - set_single_loop_fold_tree(pose, loop) - kic_refine = LoopMover_Refine_KIC(loops) - try: - kic_refine.apply(pose) - except: - raise Exception("ERROR: The KIC refiner failed!") + for loop in loops: + loops_set = Loops() + loops_set.add_loop(loop) + add_single_cutpoint_variant(pose, loop) + set_single_loop_fold_tree(pose, loop) + kic_refine = LoopMover_Refine_KIC(loops_set) + try: + kic_refine.apply(pose) + except: + raise Exception("ERROR: The KIC refiner failed!") if (decoy == 0): outputpdb = pdbfile.split(".pdb")[0] + "_K.pdb" pose.dump_pdb(outputpdb) @@ -1676,7 +1749,7 @@ def daemonLoop(): elif (aline[0:7] == "NSTRUCT"): nstruct = int(aline.split("\t")[1].strip()) f.close() - if (perturbType == "Perturb Only, Centroid" or loopType == "REFINE"): + if (perturbType == "Perturb Only, Centroid"): # or loopType == "REFINE"): os.remove("coarsekicinput") else: os.rename("coarsekicinput", "finekicinputtemp") @@ -1712,7 +1785,8 @@ def daemonLoop(): elif (os.path.isfile("finekicinput")): print "Daemon starting fine KIC loop modeling job..." try: - doKIC("Fine") + with ScanCapturing() as output: + doKIC("Fine") print "Daemon completed fine KIC loop modeling job" except Exception as e: print "The daemon crashed while performing the rotamer search job!" diff --git a/InteractiveROSETTA/scripts/docking.py b/InteractiveROSETTA/scripts/docking.py index 4c1a62d..16b709b 100644 --- a/InteractiveROSETTA/scripts/docking.py +++ b/InteractiveROSETTA/scripts/docking.py @@ -616,9 +616,19 @@ def activate(self): if (chainList != self.staticMenu.GetItems()): self.staticMenu.Clear() self.staticMenu.AppendItems(chainList) + # Take out invalid chains if the list of models changed + for i in range(len(self.staticChains)-1, -1, -1): + if (self.staticChains[i] not in chainList): + self.staticChains.pop(i) + self.updateGrid() if (chainList != self.movingMenu.GetItems()): self.movingMenu.Clear() self.movingMenu.AppendItems(chainList) + # Take out invalid chains if the list of models changed + for i in range(len(self.movingChains)-1, -1, -1): + if (self.movingChains[i] not in chainList): + self.movingChains.pop(i) + self.updateGrid() # Grab the current selection of residues for adding constraints topLefts = self.seqWin.SeqViewer.GetSelectionBlockTopLeft() bottomRights = self.seqWin.SeqViewer.GetSelectionBlockBottomRight() @@ -830,10 +840,13 @@ def pruneConstraints(self): residueMoving = True if ((residueStatic and residueMoving) or (not(residueStatic) and not(residueMoving))): self.constraints.pop(i) + continue elif (residueStatic and len(self.grdConstraints.GetCellValue(i, 4)) > 0 and not(self.grdConstraints.GetCellValue(i, 4) in self.movingChains)): self.constraints.pop(i) + continue elif (residueMoving and len(self.grdConstraints.GetCellValue(i, 4)) > 0 and not(self.grdConstraints.GetCellValue(i, 4) in self.staticChains)): self.constraints.pop(i) + continue # Now make sure the residues still exist model = self.grdConstraints.GetCellValue(i, 2) chain = model[len(model)-1] @@ -1883,6 +1896,9 @@ def loadStaticEnsb(self, event): self.lblSelStaticEnsb.SetLabel(filelabel) if (platform.system() == "Linux"): resizeTextControlForUNIX(self.lblSelStaticEnsb, 0, 320) + # Turn the server on by default if it is not already on + if (not(self.serverOn)): + self.serverToggle(event) def deleteStaticEnsb(self, event): self.ensemble1 = None @@ -1972,6 +1988,9 @@ def loadMovingEnsb(self, event): self.lblSelMovingEnsb.SetLabel(filelabel) if (platform.system() == "Linux"): resizeTextControlForUNIX(self.lblSelMovingEnsb, 0, 320) + # Turn the server on by default if it is not already on + if (not(self.serverOn)): + self.serverToggle(event) def deleteMovingEnsb(self, event): self.ensemble2 = None @@ -2040,6 +2059,8 @@ def reorient(self, event): vtranslate = vdestination - vcenter2 # Now translate self.cmd.translate(list(vtranslate), movingchainstr, camera=0) + self.cmd.center(staticchainstr + " or " + movingchainstr) + self.cmd.zoom(staticchainstr + " or " + movingchainstr) #self.stored.sum_x = 0.0 #self.stored.sum_y = 0.0 #self.stored.sum_z = 0.0 diff --git a/InteractiveROSETTA/scripts/flexpepdock.py b/InteractiveROSETTA/scripts/flexpepdock.py index d8463c4..57a076f 100644 --- a/InteractiveROSETTA/scripts/flexpepdock.py +++ b/InteractiveROSETTA/scripts/flexpepdock.py @@ -58,64 +58,76 @@ def __init__(self, parent, W, H): self.lblInst.SetForegroundColour("#FFFFFF") if (platform.system() == "Windows"): - self.lblPeptide = wx.StaticText(self, -1, "Peptide Sequence", (10, 80), (310, 20)) + self.lblPeptide = wx.StaticText(self, -1, "Peptide:", (10, 83), (90, 20)) self.lblPeptide.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) elif (platform.system() == "Darwin"): - self.lblPeptide = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblPeptide.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, 90), size=(155, 20)) + self.lblPeptide = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblPeptideSeq.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, 83), size=(90, 20)) else: - self.lblPeptide = wx.StaticText(self, -1, "Peptide Sequence", (10, 80)) + self.lblPeptide = wx.StaticText(self, -1, "Peptide:", (10, 83)) self.lblPeptide.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) self.lblPeptide.SetForegroundColour("#FFFFFF") - self.txtPeptide = wx.TextCtrl(self, -1, pos=(0, 100), size=(260, 25)) + self.peptideMenu = wx.ComboBox(self, pos=(100, 80), size=(220, 25), choices=[], style=wx.CB_READONLY) + self.peptideMenu.Bind(wx.EVT_COMBOBOX, self.peptideMenuSelect) + self.peptideMenu.SetToolTipString("Select chains that will be fixed receptors") + + if (platform.system() == "Windows"): + self.lblPeptideSeq = wx.StaticText(self, -1, "Peptide Sequence", (10, 110), (310, 20)) + self.lblPeptideSeq.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) + elif (platform.system() == "Darwin"): + self.lblPeptideSeq = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblPeptideSeq.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, 120), size=(310, 20)) + else: + self.lblPeptideSeq = wx.StaticText(self, -1, "Peptide Sequence", (10, 110)) + self.lblPeptideSeq.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) + self.lblPeptideSeq.SetForegroundColour("#FFFFFF") + self.txtPeptide = wx.TextCtrl(self, -1, pos=(0, 130), size=(260, 25)) self.txtPeptide.SetValue("") self.txtPeptide.SetToolTipString("The sequence of the flexible peptide") if (platform.system() == "Darwin"): - self.btnCreate = wx.BitmapButton(self, id=-1, bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnAddChain.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, 100), size=(77, 25)) + self.btnCreate = wx.BitmapButton(self, id=-1, bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnAddChain.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, 130), size=(77, 25)) else: - self.btnCreate = wx.Button(self, id=-1, label="Create", pos=(260, 100), size=(60, 25)) + self.btnCreate = wx.Button(self, id=-1, label="Create", pos=(260, 130), size=(60, 25)) self.btnCreate.SetForegroundColour("#000000") self.btnCreate.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) self.btnCreate.Bind(wx.EVT_BUTTON, self.createPeptide) self.btnCreate.SetToolTipString("Add selected chain to the list of static receptor chains") if (platform.system() == "Windows"): - self.lblStatic = wx.StaticText(self, -1, "Receptor Chains", (0, 130), (155, 20), wx.ALIGN_CENTRE) + self.lblStatic = wx.StaticText(self, -1, "Receptor Chains", (0, 160), (155, 20), wx.ALIGN_CENTRE) self.lblStatic.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) elif (platform.system() == "Darwin"): - self.lblStatic = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblStatic.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, 130), size=(155, 20)) + self.lblStatic = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblStatic.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, 160), size=(155, 20)) else: - self.lblStatic = wx.StaticText(self, -1, "Receptor Chains", (0, 130), style=wx.ALIGN_CENTRE) + self.lblStatic = wx.StaticText(self, -1, "Receptor Chains", (0, 160), style=wx.ALIGN_CENTRE) self.lblStatic.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) resizeTextControlForUNIX(self.lblStatic, 0, 155) self.lblStatic.SetForegroundColour("#FFFFFF") - self.staticMenu = wx.ComboBox(self, pos=(0, 150), size=(155, 25), choices=[], style=wx.CB_READONLY) + self.staticMenu = wx.ComboBox(self, pos=(0, 180), size=(155, 25), choices=[], style=wx.CB_READONLY) self.staticMenu.Bind(wx.EVT_COMBOBOX, self.staticMenuSelect) self.staticMenu.SetToolTipString("Select chains that will be fixed receptors") if (platform.system() == "Darwin"): - self.btnAddStatic = wx.BitmapButton(self, id=-1, bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnAddChain.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, 150), size=(77, 25)) + self.btnAddStatic = wx.BitmapButton(self, id=-1, bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnAddChain.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, 180), size=(77, 25)) else: - self.btnAddStatic = wx.Button(self, id=-1, label="Add", pos=(165, 150), size=(77, 25)) + self.btnAddStatic = wx.Button(self, id=-1, label="Add", pos=(165, 180), size=(77, 25)) self.btnAddStatic.SetForegroundColour("#000000") self.btnAddStatic.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) self.btnAddStatic.Bind(wx.EVT_BUTTON, self.addStatic) self.btnAddStatic.SetToolTipString("Add selected chain to the list of static receptor chains") if (platform.system() == "Darwin"): - self.btnRemoveStatic = wx.BitmapButton(self, id=-1, bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnRemoveChain.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(77, 150), size=(78, 25)) + self.btnRemoveStatic = wx.BitmapButton(self, id=-1, bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnRemoveChain.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(77, 180), size=(78, 25)) else: - self.btnRemoveStatic = wx.Button(self, id=-1, label="Remove", pos=(242, 150), size=(78, 25)) + self.btnRemoveStatic = wx.Button(self, id=-1, label="Remove", pos=(242, 180), size=(78, 25)) self.btnRemoveStatic.SetForegroundColour("#000000") self.btnRemoveStatic.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) self.btnRemoveStatic.Bind(wx.EVT_BUTTON, self.removeStatic) self.btnRemoveStatic.SetToolTipString("Remove selected chain from the list of movable docked chains") self.staticChains = [] - self.movingChains = [] self.grdDocking = wx.grid.Grid(self) self.grdDocking.CreateGrid(0, 1) self.grdDocking.SetSize((320, 100)) - self.grdDocking.SetPosition((0, 185)) + self.grdDocking.SetPosition((0, 215)) self.grdDocking.SetLabelFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) self.grdDocking.DisableDragColSize() self.grdDocking.DisableDragRowSize() @@ -364,137 +376,127 @@ def __init__(self, parent, W, H): self.lblLine.SetForegroundColour("#FFFFFF") ypos = self.lblLine.GetPosition()[1] + self.lblLine.GetSize()[1] + 10 - if (platform.system() == "Windows"): - self.lblProt3 = wx.StaticText(self, -1, "Ensemble Docking (Optional)", (0, ypos), (320, 25), wx.ALIGN_CENTRE) - self.lblProt3.SetFont(wx.Font(12, wx.DEFAULT, wx.ITALIC, wx.BOLD)) - elif (platform.system() == "Darwin"): - self.lblProt3 = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblEnsembleDocking.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(25, ypos), size=(270, 25)) - else: - self.lblProt3 = wx.StaticText(self, -1, "Ensemble Docking (Optional)", (70, ypos), style=wx.ALIGN_CENTRE) - self.lblProt3.SetFont(wx.Font(12, wx.DEFAULT, wx.ITALIC, wx.BOLD)) - resizeTextControlForUNIX(self.lblProt3, 0, self.GetSize()[0]-20) - self.lblProt3.SetForegroundColour("#FFFFFF") + #if (platform.system() == "Windows"): + # self.lblProt3 = wx.StaticText(self, -1, "Ensemble Docking (Optional)", (0, ypos), (320, 25), wx.ALIGN_CENTRE) + # self.lblProt3.SetFont(wx.Font(12, wx.DEFAULT, wx.ITALIC, wx.BOLD)) + #elif (platform.system() == "Darwin"): + # self.lblProt3 = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblEnsembleDocking.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(25, ypos), size=(270, 25)) + #else: + # self.lblProt3 = wx.StaticText(self, -1, "Ensemble Docking (Optional)", (70, ypos), style=wx.ALIGN_CENTRE) + # self.lblProt3.SetFont(wx.Font(12, wx.DEFAULT, wx.ITALIC, wx.BOLD)) + # resizeTextControlForUNIX(self.lblProt3, 0, self.GetSize()[0]-20) + #self.lblProt3.SetForegroundColour("#FFFFFF") - if (platform.system() == "Windows"): - self.lblInst3 = wx.StaticText(self, -1, "Rosetta can represent the static and/or moving\nmodels as ensembles rather than single models.\nProvide an ensemble archive (.ensb) as input for\neither structure to activate ensemble docking.", (0, ypos+30), (320, 25), wx.ALIGN_CENTRE) - self.lblInst3.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.NORMAL)) - elif (platform.system() == "Darwin"): - self.lblInst3 = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblInstConstraints.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, ypos+30), size=(320, 95)) - else: - self.lblInst3 = wx.StaticText(self, -1, "Rosetta can represent the static and/or moving\nmodels as ensembles rather than single models.\nProvide an ensemble archive (.ensb) as input for\neither structure to activate ensemble docking.", (5, ypos+30), style=wx.ALIGN_CENTRE) - self.lblInst3.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.NORMAL)) - resizeTextControlForUNIX(self.lblInst3, 0, self.GetSize()[0]-20) - self.lblInst3.SetForegroundColour("#FFFFFF") + #if (platform.system() == "Windows"): + # self.lblInst3 = wx.StaticText(self, -1, "Rosetta can represent the static and/or moving\nmodels as ensembles rather than single models.\nProvide an ensemble archive (.ensb) as input for\neither structure to activate ensemble docking.", (0, ypos+30), (320, 25), wx.ALIGN_CENTRE) + # self.lblInst3.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.NORMAL)) + #elif (platform.system() == "Darwin"): + # self.lblInst3 = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblInstConstraints.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, ypos+30), size=(320, 95)) + #else: + # self.lblInst3 = wx.StaticText(self, -1, "Rosetta can represent the static and/or moving\nmodels as ensembles rather than single models.\nProvide an ensemble archive (.ensb) as input for\neither structure to activate ensemble docking.", (5, ypos+30), style=wx.ALIGN_CENTRE) + # self.lblInst3.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.NORMAL)) + # resizeTextControlForUNIX(self.lblInst3, 0, self.GetSize()[0]-20) + #self.lblInst3.SetForegroundColour("#FFFFFF") - if (platform.system() == "Windows"): - self.lblStaticEnsb = wx.StaticText(self, -1, "Receptor Ensemble:", (0, ypos+103), (160, 20), wx.ALIGN_CENTRE) - self.lblStaticEnsb.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) - elif (platform.system() == "Darwin"): - self.lblStaticEnsb = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblStaticEnsb.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, ypos+103), size=(160, 20)) - else: - self.lblStaticEnsb = wx.StaticText(self, -1, "Receptor Ensemble:", (0, ypos+103), style=wx.ALIGN_CENTRE) - self.lblStaticEnsb.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) - resizeTextControlForUNIX(self.lblStaticEnsb, 0, 160) - self.lblStaticEnsb.SetForegroundColour("#FFFFFF") - if (platform.system() == "Darwin"): - self.btnLoadStaticEnsb = wx.BitmapButton(self, id=-1, bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnLoadStaticEnsb.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(170, ypos+100), size=(70, 25)) - else: - self.btnLoadStaticEnsb = wx.Button(self, id=-1, label="Load", pos=(170, ypos+100), size=(70, 25)) - self.btnLoadStaticEnsb.SetForegroundColour("#000000") - self.btnLoadStaticEnsb.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) - self.btnLoadStaticEnsb.Bind(wx.EVT_BUTTON, self.loadStaticEnsb) - self.btnLoadStaticEnsb.SetToolTipString("Load an ensemble archive for the static chains") - if (platform.system() == "Darwin"): - self.btnDeleteStaticEnsb = wx.BitmapButton(self, id=-1, bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnLoadStaticEnsb.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(250, ypos+100), size=(70, 25)) - else: - self.btnDeleteStaticEnsb = wx.Button(self, id=-1, label="Delete", pos=(250, ypos+100), size=(70, 25)) - self.btnDeleteStaticEnsb.SetForegroundColour("#000000") - self.btnDeleteStaticEnsb.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) - self.btnDeleteStaticEnsb.Bind(wx.EVT_BUTTON, self.deleteStaticEnsb) - self.btnDeleteStaticEnsb.SetToolTipString("Delete the loaded ensemble archive for the static chains") - if (platform.system() == "Windows"): - self.lblSelStaticEnsb = wx.StaticText(self, -1, "No Ensemble Specified", (0, ypos+133), (320, 20), wx.ALIGN_CENTRE) - self.lblSelStaticEnsb.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) - else: - self.lblSelStaticEnsb = wx.StaticText(self, -1, "No Ensemble Specified", (0, ypos+133), style=wx.ALIGN_CENTRE) - self.lblSelStaticEnsb.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) - resizeTextControlForUNIX(self.lblSelStaticEnsb, 0, 320) - self.lblSelStaticEnsb.SetForegroundColour("#FFFFFF") + #if (platform.system() == "Windows"): + # self.lblStaticEnsb = wx.StaticText(self, -1, "Receptor Ensemble:", (0, ypos+103), (160, 20), wx.ALIGN_CENTRE) + # self.lblStaticEnsb.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) + #elif (platform.system() == "Darwin"): + # self.lblStaticEnsb = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblStaticEnsb.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, ypos+103), size=(160, 20)) + #else: + # self.lblStaticEnsb = wx.StaticText(self, -1, "Receptor Ensemble:", (0, ypos+103), style=wx.ALIGN_CENTRE) + # self.lblStaticEnsb.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) + # resizeTextControlForUNIX(self.lblStaticEnsb, 0, 160) + #self.lblStaticEnsb.SetForegroundColour("#FFFFFF") + #if (platform.system() == "Darwin"): + # self.btnLoadStaticEnsb = wx.BitmapButton(self, id=-1, bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnLoadStaticEnsb.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(170, ypos+100), size=(70, 25)) + #else: + # self.btnLoadStaticEnsb = wx.Button(self, id=-1, label="Load", pos=(170, ypos+100), size=(70, 25)) + # self.btnLoadStaticEnsb.SetForegroundColour("#000000") + # self.btnLoadStaticEnsb.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) + #self.btnLoadStaticEnsb.Bind(wx.EVT_BUTTON, self.loadStaticEnsb) + #self.btnLoadStaticEnsb.SetToolTipString("Load an ensemble archive for the static chains") + #if (platform.system() == "Darwin"): + # self.btnDeleteStaticEnsb = wx.BitmapButton(self, id=-1, bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnLoadStaticEnsb.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(250, ypos+100), size=(70, 25)) + #else: + # self.btnDeleteStaticEnsb = wx.Button(self, id=-1, label="Delete", pos=(250, ypos+100), size=(70, 25)) + # self.btnDeleteStaticEnsb.SetForegroundColour("#000000") + # self.btnDeleteStaticEnsb.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) + #self.btnDeleteStaticEnsb.Bind(wx.EVT_BUTTON, self.deleteStaticEnsb) + #self.btnDeleteStaticEnsb.SetToolTipString("Delete the loaded ensemble archive for the static chains") + #if (platform.system() == "Windows"): + # self.lblSelStaticEnsb = wx.StaticText(self, -1, "No Ensemble Specified", (0, ypos+133), (320, 20), wx.ALIGN_CENTRE) + # self.lblSelStaticEnsb.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) + #else: + # self.lblSelStaticEnsb = wx.StaticText(self, -1, "No Ensemble Specified", (0, ypos+133), style=wx.ALIGN_CENTRE) + # self.lblSelStaticEnsb.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) + # resizeTextControlForUNIX(self.lblSelStaticEnsb, 0, 320) + #self.lblSelStaticEnsb.SetForegroundColour("#FFFFFF") self.ensemble1 = None self.ensemble2 = None - if (platform.system() == "Windows"): - self.lblLine2 = wx.StaticText(self, -1, "==========================", (0, ypos+160), (320, 20), wx.ALIGN_CENTRE) - self.lblLine2.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL)) - elif (platform.system() == "Darwin"): - self.lblLine2 = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblLine.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, ypos+220), size=(320, 20)) - else: - self.lblLine2 = wx.StaticText(self, -1, "==========================", (0, ypos+160), style=wx.ALIGN_CENTRE) - self.lblLine2.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL)) - resizeTextControlForUNIX(self.lblLine2, 20, 120) - self.lblLine2.SetForegroundColour("#FFFFFF") + #if (platform.system() == "Windows"): + # self.lblLine2 = wx.StaticText(self, -1, "==========================", (0, ypos+160), (320, 20), wx.ALIGN_CENTRE) + # self.lblLine2.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL)) + #elif (platform.system() == "Darwin"): + # self.lblLine2 = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblLine.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, ypos+220), size=(320, 20)) + #else: + # self.lblLine2 = wx.StaticText(self, -1, "==========================", (0, ypos+160), style=wx.ALIGN_CENTRE) + # self.lblLine2.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL)) + # resizeTextControlForUNIX(self.lblLine2, 20, 120) + #self.lblLine2.SetForegroundColour("#FFFFFF") if (platform.system() == "Windows"): - self.lblInst4 = wx.StaticText(self, -1, "After specifying constraints, click the button\nbelow to reorient the peptide near the \ninterface of the constraints.", (0, ypos+180), (320, 25), wx.ALIGN_CENTRE) + self.lblInst4 = wx.StaticText(self, -1, "After specifying constraints, click the button\nbelow to reorient the peptide near the \ninterface of the constraints.", (0, ypos), (320, 25), wx.ALIGN_CENTRE) self.lblInst4.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.NORMAL)) elif (platform.system() == "Darwin"): - self.lblInst4 = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblInstFlexPepInterface.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, ypos+180), size=(320, 95)) + self.lblInst4 = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblInstFlexPepInterface.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, ypos), size=(320, 95)) else: - self.lblInst4 = wx.StaticText(self, -1, "After specifying constraints, click the button\nbelow to reorient the peptide near the \ninterface of the constraints.", (5, ypos+180), style=wx.ALIGN_CENTRE) + self.lblInst4 = wx.StaticText(self, -1, "After specifying constraints, click the button\nbelow to reorient the peptide near the \ninterface of the constraints.", (5, ypos), style=wx.ALIGN_CENTRE) self.lblInst4.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.NORMAL)) resizeTextControlForUNIX(self.lblInst4, 0, self.GetSize()[0]-20) self.lblInst4.SetForegroundColour("#FFFFFF") if (platform.system() == "Darwin"): - self.btnReorient = wx.BitmapButton(self, id=-1, bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnReorient.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(110, ypos+230), size=(100, 25)) + self.btnReorient = wx.BitmapButton(self, id=-1, bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnReorient.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(110, ypos+50), size=(100, 25)) else: - self.btnReorient = wx.Button(self, id=-1, label="Re-orient Peptide", pos=(60, ypos+230), size=(200, 25)) + self.btnReorient = wx.Button(self, id=-1, label="Re-orient Peptide", pos=(60, ypos+50), size=(200, 25)) self.btnReorient.SetForegroundColour("#000000") self.btnReorient.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) self.btnReorient.Bind(wx.EVT_BUTTON, self.reorient) self.btnReorient.SetToolTipString("Reorient the static chain selection to point towards the ligand. Then use Fix Stat for the docking mode.") if (platform.system() == "Windows"): - self.lblCoarse = wx.StaticText(self, -1, "Coarse Models", (0, ypos+260), (155, 20), wx.ALIGN_CENTRE) - self.lblCoarse.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) + self.lblDecoys = wx.StaticText(self, -1, "Decoys", (0, ypos+80), (155, 20), wx.ALIGN_CENTRE) + self.lblDecoys.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) elif (platform.system() == "Darwin"): - self.lblCoarse = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblCoarse.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, ypos+260), size=(155, 20)) - else: - self.lblCoarse = wx.StaticText(self, -1, "Coarse Models", (0, ypos+260), style=wx.ALIGN_CENTRE) - self.lblCoarse.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) - resizeTextControlForUNIX(self.lblCoarse, 0, 155) - self.lblCoarse.SetForegroundColour("#FFFFFF") - self.txtCoarse = wx.TextCtrl(self, -1, pos=(0, ypos+280), size=(155, 25)) - self.txtCoarse.SetValue("1000") - self.txtCoarse.SetToolTipString("Number of decoys to generate in the coarse docking simulation") + self.lblDecoys = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblDecoys.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, ypos+80), size=(155, 20)) + else: + self.lblDecoys = wx.StaticText(self, -1, "Decoys", (0, ypos+80), style=wx.ALIGN_CENTRE) + self.lblDecoys.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) + resizeTextControlForUNIX(self.lblDecoys, 0, 155) + self.lblDecoys.SetForegroundColour("#FFFFFF") + self.txtDecoys = wx.TextCtrl(self, -1, pos=(0, ypos+100), size=(155, 25)) + self.txtDecoys.SetValue("1000") + self.txtDecoys.SetToolTipString("Number of decoys to generate for flexible peptide docking") if (platform.system() == "Windows"): - self.lblRefined = wx.StaticText(self, -1, "Refined Models", (165, ypos+260), (155, 20), wx.ALIGN_CENTRE) - self.lblRefined.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) + self.lblReturn = wx.StaticText(self, -1, "Return", (165, ypos+80), (155, 20), wx.ALIGN_CENTRE) + self.lblReturn.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) elif (platform.system() == "Darwin"): - self.lblRefined = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblRefined.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(165, ypos+260), size=(155, 20)) - else: - self.lblRefined = wx.StaticText(self, -1, "Refined Models", (165, ypos+260), style=wx.ALIGN_CENTRE) - self.lblRefined.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) - resizeTextControlForUNIX(self.lblRefined, 165, 155) - self.lblRefined.SetForegroundColour("#FFFFFF") - self.txtRefined = wx.TextCtrl(self, -1, pos=(165, ypos+280), size=(155, 25)) - self.txtRefined.SetValue("10") - self.txtRefined.SetToolTipString("Number of decoys to generate in the refined docking simulation that you will be able to view") + self.lblReturn = wx.StaticBitmap(self, -1, wx.Image(self.parent.parent.scriptdir + "/images/osx/lblReturn.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(165, ypos+80), size=(155, 20)) + else: + self.lblReturn = wx.StaticText(self, -1, "Return", (165, ypos+80), style=wx.ALIGN_CENTRE) + self.lblReturn.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)) + resizeTextControlForUNIX(self.lblReturn, 165, 155) + self.lblReturn.SetForegroundColour("#FFFFFF") + self.txtReturn = wx.TextCtrl(self, -1, pos=(165, ypos+100), size=(155, 25)) + self.txtReturn.SetValue("10") + self.txtReturn.SetToolTipString("Number of decoys to generate in the refined docking simulation that you will be able to view") if (platform.system() == "Darwin"): - self.btnServerToggle = wx.BitmapButton(self, id=-1, bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnServerOff.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(0, ypos+310), size=(100, 25)) + self.btnDock = wx.BitmapButton(self, id=-1, bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnDock.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(220, ypos+130), size=(100, 25)) else: - self.btnServerToggle = wx.Button(self, id=-1, label="Server Off", pos=(40, ypos+310), size=(100, 25)) - self.btnServerToggle.SetForegroundColour("#000000") - self.btnServerToggle.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.BOLD)) - self.btnServerToggle.Bind(wx.EVT_BUTTON, self.serverToggle) - self.btnServerToggle.SetToolTipString("Perform docking simulations locally") - self.serverOn = False - - if (platform.system() == "Darwin"): - self.btnDock = wx.BitmapButton(self, id=-1, bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnDock.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap(), pos=(220, ypos+310), size=(100, 25)) - else: - self.btnDock = wx.Button(self, id=-1, label="Dock!", pos=(180, ypos+310), size=(100, 25)) + self.btnDock = wx.Button(self, id=-1, label="Dock!", pos=(110, ypos+130), size=(100, 25)) self.btnDock.SetForegroundColour("#000000") self.btnDock.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.BOLD)) self.btnDock.Bind(wx.EVT_BUTTON, self.dockClick) @@ -533,15 +535,35 @@ def setSelectWin(self, selectWin): def activate(self): # Get the list of all the chains in the sequence viewer chainList = [] + peptideList = [] + peptideStillThere = False for r in range(0, self.seqWin.SeqViewer.NumberRows): - chainList.append(self.seqWin.IDs[r]) + if (self.seqWin.IDs[r] != "flexpeptide|P"): + chainList.append(self.seqWin.IDs[r]) + else: + peptideStillThere = True + if (len(self.seqWin.sequences[r]) <= 30): + peptideList.append(self.seqWin.IDs[r]) + if (not(peptideStillThere)): + self.movingChains = [] # Update the combobox list if the list has changed if (chainList != self.staticMenu.GetItems()): self.staticMenu.Clear() self.staticMenu.AppendItems(chainList) - if (chainList != self.movingMenu.GetItems()): - self.movingMenu.Clear() - self.movingMenu.AppendItems(chainList) + # Take out invalid chains if the list of models changed + for i in range(len(self.staticChains)-1, -1, -1): + if (self.staticChains[i] not in chainList): + self.staticChains.pop(i) + self.updateGrid() + # Update the combobox list if the list has changed + if (peptideList != self.peptideMenu.GetItems()): + self.peptideMenu.Clear() + self.peptideMenu.AppendItems(peptideList) + # Take out invalid chains if the list of models changed + for i in range(len(self.movingChains)-1, -1, -1): + if (self.movingChains[i] not in peptideList): + self.movingChains.pop(i) + self.peptideMenu.SetSelection(0) # Grab the current selection of residues for adding constraints topLefts = self.seqWin.SeqViewer.GetSelectionBlockTopLeft() bottomRights = self.seqWin.SeqViewer.GetSelectionBlockBottomRight() @@ -589,12 +611,76 @@ def movingMenuSelect(self, event): #self.showChain(self.movingMenu.GetStringSelection()) def createPeptide(self, event): - pass - + # Is the sequence valid? + if (len(self.txtPeptide.GetValue().strip()) == 0): + dlg = wx.MessageDialog(self, "Please specify the sequence of the flexible peptide that will be modeled.", "No Peptide Given", wx.OK | wx.ICON_ERROR | wx.CENTRE) + dlg.ShowModal() + dlg.Destroy() + return + sequence = self.txtPeptide.GetValue().strip().upper() + sequence = sequence.replace(" ", "").replace("\t", "").replace("\n", "") + for AA in sequence: + if (AA not in "ACDEFGHIKLMNPQRSTVWY"): + dlg = wx.MessageDialog(self, "An unrecognized amino acid was found in the peptide sequence: " + AA, "Unrecognized Amino Acid", wx.OK | wx.ICON_ERROR | wx.CENTRE) + dlg.ShowModal() + dlg.Destroy() + return + # Is it too long? + if (len(sequence) > 30): + dlg = wx.MessageDialog(self, "Your peptide is too long. The maximum length is 30 residues, but most of the benchmarks were performed on peptides of length 5-15 residues.", "Peptide Too Long", wx.OK | wx.ICON_ERROR | wx.CENTRE) + dlg.ShowModal() + dlg.Destroy() + return + # Unload a previously created peptide if it exists + for r in range(0, len(self.seqWin.IDs)): + if (self.seqWin.IDs[r] == "flexpeptide|P"): + self.seqWin.deleteChain(r) + break + # Create an extended peptide with the given sequence + for AA in sequence: + self.cmd._alt(AA.lower()) + # Load it in the sequence window + goToSandbox() + self.cmd.alter("pkmol", "chain=\"P\"") + self.cmd.save("flexpeptide.pdb", "pkmol") + self.cmd.remove("pkmol") + self.cmd.delete("pkmol") + self.cmd.remove("pk1") + self.cmd.delete("pk1") + for three in "ala cys asp glu phe gly his ile lys leu met asn pro gln arg ser thr val trp tyr".split(): + try: + self.cmd.remove(three) + self.cmd.delete(three) + except: + pass + # The peptide gets weird numbering for some reason, so let's renumber from one + fin = open("flexpeptide.pdb", "r") + data = [] + for aline in fin: + data.append(aline) + fin.close() + fout = open("flexpeptide.pdb", "w") + lastres = "0000" + indx = 0 + for aline in data: + if (aline.startswith("ATOM") and aline[22:26] != lastres): + lastres = aline[22:26] + indx += 1 + if (aline.startswith("ATOM")): + aline = aline[0:22] + "%4.4i" % indx + aline[26:] + fout.write(aline) + fout.close() + self.seqWin.PyMOLPDBLoad(1, "flexpeptide.pdb", flexiblePeptide=True) + self.movingChains = ["flexpeptide|P"] + # Select the created peptide automatically + self.activate() + indx = self.peptideMenu.GetItems().index("flexpeptide|P") + self.peptideMenu.SetSelection(indx) + def updateGrid(self): if (self.grdDocking.NumberRows > 0): self.grdDocking.DeleteRows(0, self.grdDocking.NumberRows) - for i in range(0, max(len(self.staticChains), len(self.movingChains))): + for i in range(0, len(self.staticChains)): self.grdDocking.AppendRows(1) readOnly = wx.grid.GridCellAttr() readOnly.SetReadOnly(True) @@ -602,9 +688,7 @@ def updateGrid(self): self.grdDocking.SetCellAlignment(i, 0, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE) self.grdDocking.SetRowLabelValue(i, "") for i in range(0, len(self.staticChains)): - self.grdDocking.SetRowLabelValue(i, self.staticChains[i]) - for i in range(0, len(self.movingChains)): - self.grdDocking.SetCellValue(i, 0, self.movingChains[i]) + self.grdDocking.SetCellValue(i, 0, self.staticChains[i]) def addStatic(self, event): # Add this to the list of chains that will be fixed @@ -621,7 +705,6 @@ def addStatic(self, event): # Update the grid with this new information self.updateGrid() self.pruneConstraints() - self.deleteStaticEnsb(None) # Ensemble data is not valid anymore, remove it logInfo("Added " + chain + " to the list of static chains") def removeStatic(self, event): @@ -633,13 +716,12 @@ def removeStatic(self, event): # Update the grid with this new information self.updateGrid() self.pruneConstraints() - self.deleteStaticEnsb(None) # Ensemble data is not valid anymore, remove it logInfo("Removed " + chain + " from the list of static chains") - def addMoving(self, event): + def peptideMenuSelect(self, event): # Add this to the list of chains that will be docked # If this chain is already in the static list then we need to take it out of that list and put it as movable - chain = str(self.movingMenu.GetStringSelection()) + chain = str(self.peptideMenu.GetStringSelection()) if (len(chain.strip()) == 0): return if (not(chain in self.movingChains)): @@ -648,11 +730,8 @@ def addMoving(self, event): if (chain in self.staticChains): indx = self.staticChains.index(chain) self.staticChains.pop(indx) - # Update the grid with this new information - self.updateGrid() self.pruneConstraints() - self.deleteMovingEnsb(None) # Ensemble data is not valid anymore, remove it - logInfo("Added " + chain + " to the list of moving chains") + logInfo("Selected " + chain + " as a peptide chain") def removeMoving(self, event): # Just pop out the indicated chain @@ -756,10 +835,13 @@ def pruneConstraints(self): residueMoving = True if ((residueStatic and residueMoving) or (not(residueStatic) and not(residueMoving))): self.constraints.pop(i) + continue elif (residueStatic and len(self.grdConstraints.GetCellValue(i, 4)) > 0 and not(self.grdConstraints.GetCellValue(i, 4) in self.movingChains)): self.constraints.pop(i) + continue elif (residueMoving and len(self.grdConstraints.GetCellValue(i, 4)) > 0 and not(self.grdConstraints.GetCellValue(i, 4) in self.staticChains)): self.constraints.pop(i) + continue # Now make sure the residues still exist model = self.grdConstraints.GetCellValue(i, 2) chain = model[len(model)-1] @@ -1635,6 +1717,9 @@ def writeSinglePDB(self): pose.add(m) else: pose[0].add(posechain) + # Get the receptor and peptide chain lists + self.receptorChains = usedChains[0:len(usedChains)-1] + self.peptideChain = usedChains[len(usedChains)-1] self.dockpdbname = str(chains[0][0:len(chains[0])-2]) + "_dock.pdb" self.seqWin.pdbwriter.set_structure(pose) self.seqWin.pdbwriter.save(self.dockpdbname) @@ -1727,184 +1812,6 @@ def saveClick(self, event): else: logInfo("Cancelled save operation") - def loadStaticEnsb(self, event): - logInfo("Load Static Ensemble button clicked") - # If no static chain has been specified, abort because we cannot check to make sure the ensemble - # and the static chains are compatible - if (len(self.staticChains) == 0): - dlg = wx.MessageDialog(self, "Please specify which chains are in the static structure before specifying an ensemble.", "No Static Structure", wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE) - dlg.ShowModal() - dlg.Destroy() - return - dlg = wx.FileDialog( - self, message="Choose a File", - defaultDir=self.seqWin.cwd, - defaultFile="", - wildcard="Ensemble Archives (*.ensb)|*.ensb", - style=wx.OPEN | wx.CHANGE_DIR) - if (dlg.ShowModal() == wx.ID_OK): - paths = dlg.GetPaths() - # Change cwd to the last opened file - if (platform.system() == "Windows"): - lastDirIndx = paths[len(paths)-1].rfind("\\") - else: - lastDirIndx = paths[len(paths)-1].rfind("/") - self.seqWin.cwd = str(paths[len(paths)-1][0:lastDirIndx]) - self.seqWin.saveWindowData(None) - filename = str(paths[0]) - filelabel = filename[lastDirIndx+1:] - # Does it open? If yes, then erase the resfile data and continue - try: - fin = gzip.open(filename, "r") - except: - wx.MessageBox("The file " + filename.strip() + " cannot be opened!", "File Cannot Be Read", wx.OK|wx.ICON_EXCLAMATION) - return - logInfo("Loaded data from an ensemble archive", filename) - # Now we have to read the first model in the archive, find its chains and sequences, and make - # sure they all match what is already loaded in the static chains - readingData = False - modeldata = {} - lastres = " 0000" - for aline in fin: - if (aline.startswith("BEGIN PDB")): - readingData = True - elif (aline.startswith("END PDB")): - break - elif (readingData and (aline.startswith("ATOM") or aline.startswith("HETATM"))): - chain = aline[21] - if (len(chain.strip()) == 0): - chain = "_" - if (chain + aline[22:27] != lastres): - lastres = chain + aline[22:27] - try: - modeldata[chain] += AA3to1(aline[17:20]) - except: - modeldata[chain] = AA3to1(aline[17:20]) - fin.close() - # Now check against the static chains loaded - for modelchain in self.staticChains: - chain = modelchain[len(modelchain)-1] - for i in range(0, len(self.seqWin.IDs)): - if (modelchain == self.seqWin.IDs[i]): - try: - if (modeldata[chain] != self.seqWin.sequences[i]): - dlg = wx.MessageDialog(self, "The sequences for chain " + chain + " do not match between the specified static chains and the selected ensemble.", "Ensemble Data Mismatch", wx.OK | wx.ICON_ERROR | wx.CENTRE) - dlg.ShowModal() - dlg.Destroy() - return - except: - dlg = wx.MessageDialog(self, "Chain " + chain + " in the static chains is not in the ensemble", "Ensemble Data Mismatch", wx.OK | wx.ICON_ERROR | wx.CENTRE) - dlg.ShowModal() - dlg.Destroy() - return - modeldata.pop(chain) - # Are there extra chains left over from the ensemble? - if (len(modeldata.keys()) > 0): - dlg = wx.MessageDialog(self, "Chain " + modeldata.keys()[0] + " does not exist in the specified static chains.", "Ensemble Data Mismatch", wx.OK | wx.ICON_ERROR | wx.CENTRE) - dlg.ShowModal() - dlg.Destroy() - return - # If we got this far, then the ensemble should be okay - self.ensemble1 = filename - self.lblSelStaticEnsb.SetLabel(filelabel) - if (platform.system() == "Linux"): - resizeTextControlForUNIX(self.lblSelStaticEnsb, 0, 320) - - def deleteStaticEnsb(self, event): - self.ensemble1 = None - self.lblSelStaticEnsb.SetLabel("No Ensemble Specified") - if (platform.system() == "Linux"): - resizeTextControlForUNIX(self.lblSelStaticEnsb, 0, 320) - - def loadMovingEnsb(self, event): - logInfo("Load Moving Ensemble button clicked") - # If no static chain has been specified, abort because we cannot check to make sure the ensemble - # and the static chains are compatible - if (len(self.movingChains) == 0): - dlg = wx.MessageDialog(self, "Please specify which chains are in the moving structure before specifying an ensemble.", "No Moving Structure", wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE) - dlg.ShowModal() - dlg.Destroy() - return - dlg = wx.FileDialog( - self, message="Choose a File", - defaultDir=self.seqWin.cwd, - defaultFile="", - wildcard="Ensemble Archives (*.ensb)|*.ensb", - style=wx.OPEN | wx.CHANGE_DIR) - if (dlg.ShowModal() == wx.ID_OK): - paths = dlg.GetPaths() - # Change cwd to the last opened file - if (platform.system() == "Windows"): - lastDirIndx = paths[len(paths)-1].rfind("\\") - else: - lastDirIndx = paths[len(paths)-1].rfind("/") - self.seqWin.cwd = str(paths[len(paths)-1][0:lastDirIndx]) - self.seqWin.saveWindowData(None) - filename = str(paths[0]) - filelabel = filename[lastDirIndx+1:] - # Does it open? If yes, then erase the resfile data and continue - try: - fin = gzip.open(filename, "r") - except: - wx.MessageBox("The file " + filename.strip() + " cannot be opened!", "File Cannot Be Read", wx.OK|wx.ICON_EXCLAMATION) - return - logInfo("Loaded data from an ensemble archive", filename) - # Now we have to read the first model in the archive, find its chains and sequences, and make - # sure they all match what is already loaded in the static chains - readingData = False - modeldata = {} - lastres = " 0000" - for aline in fin: - if (aline.startswith("BEGIN PDB")): - readingData = True - elif (aline.startswith("END PDB")): - break - elif (readingData and (aline.startswith("ATOM") or aline.startswith("HETATM"))): - chain = aline[21] - if (len(chain.strip()) == 0): - chain = "_" - if (chain + aline[22:27] != lastres): - lastres = chain + aline[22:27] - try: - modeldata[chain] += AA3to1(aline[17:20]) - except: - modeldata[chain] = AA3to1(aline[17:20]) - fin.close() - # Now check against the moving chains loaded - for modelchain in self.movingChains: - chain = modelchain[len(modelchain)-1] - for i in range(0, len(self.seqWin.IDs)): - if (modelchain == self.seqWin.IDs[i]): - try: - if (modeldata[chain] != self.seqWin.sequences[i]): - dlg = wx.MessageDialog(self, "The sequences for chain " + chain + " do not match between the specified moving chains and the selected ensemble.", "Ensemble Data Mismatch", wx.OK | wx.ICON_ERROR | wx.CENTRE) - dlg.ShowModal() - dlg.Destroy() - return - except: - dlg = wx.MessageDialog(self, "Chain " + chain + " in the moving chains is not in the ensemble", "Ensemble Data Mismatch", wx.OK | wx.ICON_ERROR | wx.CENTRE) - dlg.ShowModal() - dlg.Destroy() - return - modeldata.pop(chain) - # Are there extra chains left over from the ensemble? - if (len(modeldata.keys()) > 0): - dlg = wx.MessageDialog(self, "Chain " + modeldata.keys()[0] + " does not exist in the specified moving chains.", "Ensemble Data Mismatch", wx.OK | wx.ICON_ERROR | wx.CENTRE) - dlg.ShowModal() - dlg.Destroy() - return - # If we got this far, then the ensemble should be okay - self.ensemble2 = filename - self.lblSelMovingEnsb.SetLabel(filelabel) - if (platform.system() == "Linux"): - resizeTextControlForUNIX(self.lblSelMovingEnsb, 0, 320) - - def deleteMovingEnsb(self, event): - self.ensemble2 = None - self.lblSelMovingEnsb.SetLabel("No Ensemble Specified") - if (platform.system() == "Linux"): - resizeTextControlForUNIX(self.lblSelMovingEnsb, 0, 320) - def reorient(self, event): #from pymol.cgo import * # First find the interface in the current selection that are on the static chains @@ -1927,7 +1834,31 @@ def reorient(self, event): else: movingchainstr += "(model " + model + " and chain " + chainID + ") or " movingchainstr = movingchainstr[0:len(movingchainstr)-4] + ")" + # Now get residues in the receptor constraints + cststr = "(" + cstfound = False + for constraint in self.constraints: + modelchain = constraint[1].split(":")[0] + if (constraint[0] == "Site" and modelchain not in self.staticChains): + continue + cstfound = True + resi = constraint[1].split(":")[1] + resi = resi[0:len(resi)-1] + model = modelchain[0:len(modelchain)-2] + chain = modelchain[len(modelchain)-1] + if (chain == "_"): + cststr += "(model " + model + " and resi " + resi + ") or " + else: + cststr += "(model " + model + " and chain " + chain + " and resi " + resi + ") or " + if (not(cstfound)): + dlg = wx.MessageDialog(self, "The binding interface cannot be determined without constraints that specify receptor residues at the interface.", "No Receptor Constraints", wx.OK|wx.ICON_ERROR) + dlg.ShowModal() + dlg.Destroy() + cststr = cststr[0:len(cststr)-4] + ")" try: + # First, superimpose the peptide Ca atoms on top of the interface Ca atoms to get + # it oriented properly, later we'll move it out + self.cmd.align(movingchainstr + " and name ca", cststr + " and name ca", cycles=0) # Now find the average center point of all atoms in this chainset self.stored.sum_x = 0.0 self.stored.sum_y = 0.0 @@ -1943,15 +1874,15 @@ def reorient(self, event): self.stored.sum_y = 0.0 self.stored.sum_z = 0.0 self.stored.n = 0 - self.cmd.iterate_state(1, staticchainstr + " and seqsele and name ca", "stored.sum_x += x; stored.sum_y +=y; stored.sum_z += z; stored.n += 1") + self.cmd.iterate_state(1, cststr + " and name ca", "stored.sum_x += x; stored.sum_y +=y; stored.sum_z += z; stored.n += 1") interface_x = self.stored.sum_x / float(self.stored.n) interface_y = self.stored.sum_y / float(self.stored.n) interface_z = self.stored.sum_z / float(self.stored.n) vinterface = numpy.array([interface_x, interface_y, interface_z]) # Now calculate the destination of the opposing chain - # It will be along the line between these previous two points, four times the distance between them + # It will be along the line between these previous two points vtranslate = vinterface - vcenter - vdestination = vinterface + 4*vtranslate + vdestination = vinterface + 0.5*vtranslate # Now calculate the center of mass of the other chainset self.stored.sum_x = 0.0 self.stored.sum_y = 0.0 @@ -1966,6 +1897,8 @@ def reorient(self, event): vtranslate = vdestination - vcenter2 # Now translate self.cmd.translate(list(vtranslate), movingchainstr, camera=0) + self.cmd.center(staticchainstr + " or " + movingchainstr) + self.cmd.zoom(staticchainstr + " or " + movingchainstr) #self.stored.sum_x = 0.0 #self.stored.sum_y = 0.0 #self.stored.sum_z = 0.0 @@ -1989,74 +1922,16 @@ def reorient(self, event): except: pass - def cancelDock(self): - logInfo("Canceled docking operation") - try: - self.progress.Destroy() - except: - pass - try: - os.remove("coarsedockinput") - except: - pass - try: - os.remove("coarsedockinputtemp") - except: - pass - try: - os.remove("repackmedock_0.pdb") - except: - pass - try: - os.remove("finedockinput") - except: - pass - self.tmrDock.Stop() - self.seqWin.cannotDelete = False - self.parent.GoBtn.Enable() - self.btnAddStatic.Enable() - self.btnRemoveStatic.Enable() - self.btnAddMoving.Enable() - self.btnRemoveMoving.Enable() - self.btnStarting.Enable() - if (platform.system() == "Darwin"): - self.btnDock.SetBitmapLabel(bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnDock.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap()) - else: - self.btnDock.SetLabel("Dock!") - self.buttonState = "Dock!" - self.btnDock.SetToolTipString("Perform docking simulation with selected parameters") - deleteInputFiles() - self.parent.parent.restartDaemon() - # Get rid of the messages - for i in range(0, len(self.seqWin.msgQueue)): - if (self.seqWin.msgQueue[i].find("Performing protein docking") >= 0): - self.seqWin.msgQueue.pop(i) - break - for i in range(0, len(self.seqWin.msgQueue)): - if (self.seqWin.msgQueue[i].find("Performing rotamer repacking") >= 0): - self.seqWin.msgQueue.pop(i) - break - for i in range(0, len(self.seqWin.msgQueue)): - if (self.seqWin.msgQueue[i].find("Performing refined protein docking") >= 0): - self.seqWin.msgQueue.pop(i) - break - if (len(self.seqWin.msgQueue) > 0): - self.seqWin.labelMsg.SetLabel(self.seqWin.msgQueue[len(self.seqWin.msgQueue)-1]) - else: - self.seqWin.labelMsg.SetLabel("") - self.seqWin.labelMsg.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.BOLD)) - self.seqWin.labelMsg.SetForegroundColour("#FFFFFF") - def dockClick(self, event): # This is also the "Finalize!" button if (self.buttonState == "Dock!"): # Make sure that there is at least one chain in each of the lists and that the fixed chain list includes # a polypeptide chain if (len(self.staticChains) == 0): - wx.MessageBox("Please indicate a chain that will serve as the receptor!", "Static Chain Required", wx.OK|wx.ICON_EXCLAMATION) + wx.MessageBox("Please indicate a chain that will serve as the receptor!", "Receptor Chain Required", wx.OK|wx.ICON_EXCLAMATION) return if (len(self.movingChains) == 0): - wx.MessageBox("Please indicate a chain that will serve as the docked structure!", "Movable Chain Required", wx.OK|wx.ICON_EXCLAMATION) + wx.MessageBox("Please provide a flexible peptide ligand or create one!", "Flexible Peptide Required", wx.OK|wx.ICON_EXCLAMATION) return ispolypeptide = False for ID in self.staticChains: @@ -2072,244 +1947,35 @@ def dockClick(self, event): return # Are the decoy numbers valid? try: - n = int(self.txtCoarse.GetValue()) + n = int(self.txtDecoys.GetValue()) if (n <= 0): raise Exception("Coarse decoy number not a positive integer") except: wx.MessageBox("Please enter a positive integer for the number of coarse decoys.", "Invalid Number of Coarse Decoys", wx.OK|wx.ICON_EXCLAMATION) return try: - n = int(self.txtRefined.GetValue()) + n = int(self.txtReturn.GetValue()) if (n <= 0): raise Exception("Refined decoy number not a positive integer") except: wx.MessageBox("Please enter a positive integer for the number of refined decoys.", "Invalid Number of Refined Decoys", wx.OK|wx.ICON_EXCLAMATION) return - # Ensemble docking is only available on the server - if ((self.ensemble1 or self.ensemble2) and not(self.serverOn)): - dlg = wx.MessageDialog(self, "Ensemble docking is only available through the Rosetta server. Would you like to enable server mode?", "Server Needed for EnsembleDock", wx.YES_NO | wx.ICON_QUESTION | wx.CENTRE) - if (dlg.ShowModal() == wx.ID_YES): - self.serverToggle(None) - else: - return - dlg.Destroy() - self.seqWin.labelMsg.SetLabel("Performing protein docking, please be patient...") - self.seqWin.labelMsg.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.BOLD)) - self.seqWin.labelMsg.SetForegroundColour("#FFFFFF") - self.seqWin.msgQueue.append("Performing protein docking, please be patient...") - self.seqWin.cannotDelete = True - self.parent.GoBtn.Disable() self.btnAddStatic.Disable() self.btnRemoveStatic.Disable() - self.btnAddMoving.Disable() - self.btnRemoveMoving.Disable() - self.btnStarting.Disable() - if (platform.system() == "Darwin"): - self.btnDock.SetBitmapLabel(bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnDock_Cancel.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap()) - else: - self.btnDock.SetLabel("Cancel!") - self.buttonState = "Cancel!" - self.btnDock.SetToolTipString("Cancel the docking simulation") self.stage = 1 - #thrKIC = Thread(target=self.threadKIC, args=()) - #thrKIC.start() logInfo("Clicked the Dock button") goToSandbox() - self.tmrDock = wx.Timer(self) - self.Bind(wx.EVT_TIMER, self.threadDock, self.tmrDock) self.writeSinglePDB() - self.parent.parent.restartDaemon() - self.tmrDock.Start(1000) - elif (self.buttonState == "Cancel!"): - dlg = wx.MessageDialog(self, "Are you sure you want to cancel the docking simulation? All progress will be lost.", "Cancel Docking Simulation", wx.YES_NO | wx.ICON_QUESTION | wx.CENTRE) - result = dlg.ShowModal() - if (result == wx.ID_YES): - self.cancelDock() - dlg.Destroy() - else: - # Finalize button, ask whether the changes will be accepted or rejected - dlg = wx.MessageDialog(self, "Do you want to accept the results of this docking session?", "Accept/Reject Model", wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION | wx.CENTRE) - result = dlg.ShowModal() - if (result == wx.ID_YES): - logInfo("Accepted docked model") - accept = True - # Get a filename prefix for these models - while (True): - dlg3 = wx.FileDialog( - self, message="Save a PDB File", - defaultDir=self.seqWin.cwd, - defaultFile=self.staticChains[0][0:len(self.staticChains[0])-2], - wildcard="PDB Files (*.pdb)|*.pdb", - style=wx.SAVE | wx.CHANGE_DIR) - if (dlg3.ShowModal() == wx.ID_OK): - path = dlg3.GetPath() - # Change cwd to the last opened file - if (platform.system() == "Windows"): - lastDirIndx = path.rfind("\\") - else: - lastDirIndx = path.rfind("/") - self.seqWin.cwd = str(path[0:lastDirIndx]) - self.seqWin.saveWindowData(None) - # Load the PDBs into PyMOL - filename = str(path).split(".pdb")[0] + "_0001.pdb" - # Does it exist already? If so, ask if the user really wants to overwrite it - if (os.path.isfile(filename)): - dlg2 = wx.MessageDialog(self, "The file " + filename + " already exists. Overwrite it?", "Filename Already Exists", wx.YES_NO | wx.ICON_QUESTION | wx.CENTRE) - if (dlg2.ShowModal() == wx.ID_NO): - dlg2.Destroy() - continue - dlg2.Destroy() - else: - # Default to cancel behavior - dlg.Destroy() - return - filename = filename.split("_0001.pdb")[0] + ".pdb" - break - elif (result == wx.ID_NO): - logInfo("Rejected docked model") - accept = False - else: - logInfo("Canceled Finalize operation") - dlg.Destroy() - return - dlg.Destroy() - self.viewMenu.Disable() - self.parent.GoBtn.Enable() - self.btnAddStatic.Enable() - self.btnRemoveStatic.Enable() - self.btnAddMoving.Enable() - self.btnRemoveMoving.Enable() - self.btnStarting.Enable() - self.grdDocking.ClearGrid() - if (platform.system() == "Darwin"): - self.btnDock.SetBitmapLabel(bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnDock.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap()) - else: - self.btnDock.SetLabel("Dock!") - self.buttonState = "Dock!" - self.btnDock.SetToolTipString("Perform docking simulation with selected parameters") - #self.btnSave.Disable() - self.cmd.label("all", "") - self.seqWin.cannotDelete = False - if (not(accept)): - self.cmd.remove("dock_view") - self.cmd.delete("dock_view") - return - # Get rid of the original chains, save the docked pose, and reload the structure in PyMOL - for ID in self.staticChains: - row = self.seqWin.IDs.index(ID) - self.seqWin.deleteChain(row) - for ID in self.movingChains: - row = self.seqWin.IDs.index(ID) - self.seqWin.deleteChain(row) - newname = filename.split(".pdb")[0] - if (platform.system() == "Windows"): - newID = newname[newname.rfind("\\")+1:] - else: - newID = newname[newname.rfind("/")+1:] - self.movingChains = [] - self.staticChains = [] - #if (platform.system() == "Windows"): - #newname = os.path.expanduser("~") + "\\InteractiveROSETTA\\" + newID - #else: - #newname = os.path.expanduser("~") + "/InteractiveROSETTA/" + newID - for i in range(0, len(self.viewMenu.GetItems())): - if (self.selectedModel == self.viewMenu.GetItems()[i]): - realID = newID + "_%4.4i" % (i+1) - realname = newname + "_%4.4i" % (i+1) + ".pdb" + # Write the input file + f = open("flexpepinputtemp", "w") + f.write("PDBFILE\t" + self.dockpdbname.strip() + "\n") + while (True): try: - os.rename(self.viewMenu.GetItems()[i], newname + "_%4.4i" % (i+1) + ".pdb") + f2 = open(self.dockpdbname.strip(), "r") except: - # Windows may complain if the file already exists - try: - os.remove(newname + "_%4.4i" % (i+1) + ".pdb") - os.rename(self.viewMenu.GetItems()[i], newname + "_%4.4i" % (i+1) + ".pdb") - except: - print "ERROR: Could not load the docked structure into the Sequence Window" - if (platform.system() == "Windows"): - print "The model is currently at " + self.selectedModel + " in " + os.path.expanduser("~") + "\\InteractiveROSETTA" - else: - print "The model is currently at " + self.selectedModel + " in " + os.path.expanduser("~") + "/InteractiveROSETTA" - try: - self.cmd.remove("dock_view") - self.cmd.delete("dock_view") - self.cmd.load(realname, realID) - self.seqWin.PyMOLPDBLoad(0, realname) - defaultPyMOLView(self.cmd, realID) - del self.dockView - except: - # Some weird error happened, do nothing instead of crashing - print "Bug at accept button click" - pass - - def recoverFromError(self, msg=""): - # This function tells the user what the error was and tries to revert the protocol - # back to the pre-daemon state so the main GUI can continue to be used - if (len(msg) == 0): - f = open("errreport", "r") - errmsg = "An error was encountered during the protocol:\n\n" - for aline in f: - errmsg = errmsg + str(aline) - f.close() - os.remove("errreport") - else: - errmsg = msg - logInfo("Error Encountered") - logInfo(errmsg) - if (platform.system() == "Windows"): - sessioninfo = os.path.expanduser("~") + "\\InteractiveRosetta\\sessionlog" - else: - sessioninfo = os.path.expanduser("~") + "/InteractiveRosetta/sessionlog" - errmsg = errmsg + "\n\nIf you don't know what caused this, send the file " + sessioninfo + " to a developer along with an explanation of what you did." - # You have to use a MessageDialog because the MessageBox doesn't always work for some reason - dlg = wx.MessageDialog(self, errmsg, "Error Encountered", wx.OK|wx.ICON_EXCLAMATION) - dlg.ShowModal() - dlg.Destroy() - self.seqWin.cannotDelete = False - self.parent.GoBtn.Enable() - self.btnAddStatic.Enable() - self.btnRemoveStatic.Enable() - self.btnAddMoving.Enable() - self.btnRemoveMoving.Enable() - self.btnDock.Enable() - if (platform.system() == "Darwin"): - self.btnDock.SetBitmapLabel(bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnDock.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap()) - else: - self.btnDock.SetLabel("Dock!") - self.buttonState = "Dock!" - self.btnDock.SetToolTipString("Perform docking simulation with selected parameters") - # Get rid of the messages - for i in range(0, len(self.seqWin.msgQueue)): - if (self.seqWin.msgQueue[i].find("Performing protein docking") >= 0): - self.seqWin.msgQueue.pop(i) - break - for i in range(0, len(self.seqWin.msgQueue)): - if (self.seqWin.msgQueue[i].find("Performing rotamer repacking") >= 0): - self.seqWin.msgQueue.pop(i) - break - for i in range(0, len(self.seqWin.msgQueue)): - if (self.seqWin.msgQueue[i].find("Performing refined protein docking") >= 0): - self.seqWin.msgQueue.pop(i) + # Might not have finished writing it yet + continue break - if (len(self.seqWin.msgQueue) > 0): - self.seqWin.labelMsg.SetLabel(self.seqWin.msgQueue[len(self.seqWin.msgQueue)-1]) - else: - self.seqWin.labelMsg.SetLabel("") - self.seqWin.labelMsg.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.BOLD)) - self.seqWin.labelMsg.SetForegroundColour("#FFFFFF") - - def threadDock(self, event): - # Dump a file with the loop modeling parameters for the daemon to pick up - goToSandbox() - if (self.stage == 1): - self.tmrDock.Stop() - self.timeoutCount = 0 - f = open("coarsedockinputtemp", "w") - f.write("PDBFILE\t" + self.dockpdbname.strip() + "\n") - try: - f2 = open(self.dockpdbname.strip(), "r") - except: - # Might not have finished writing it yet - return f.write("BEGIN PDB DATA\n") for aline in f2: f.write(aline.strip() + "\n") @@ -2324,260 +1990,38 @@ def threadDock(self, event): f2.close() except: pass - f.write("JUMPCONFIG\t" + self.jumpconfig + "\n") - f.write("ORIENT\t" + self.startingType + "\n") - f.write("COARSEDECOYS\t" + self.txtCoarse.GetValue() + "\n") - f.write("REFINEDDECOYS\t" + self.txtRefined.GetValue() + "\n") - if (self.ensemble1): - fin = gzip.open(self.ensemble1, "r") - f.write("BEGIN ENSEMBLE1 DATA\n") - for aline in fin: - f.write(aline) - f.write("END ENSEMBLE1 DATA\n") - fin.close() - if (self.ensemble2): - fin = gzip.open(self.ensemble2, "r") - f.write("BEGIN ENSEMBLE2 DATA\n") - for aline in fin: - f.write(aline) - f.write("END ENSEMBLE2 DATA\n") - fin.close() - f.close() - appendScorefxnParamsInfoToFile("coarsedockinputtemp", self.selectWin.weightsfile) - if (self.serverOn): - try: - self.ID = sendToServer("coarsedockinput") - # First make sure this isn't a duplicate - alreadythere = False - try: - f = open("downloadwatch", "r") - for aline in f: - if (len(aline.split("\t")) >= 2 and aline.split("\t")[0] == "DOCK" and aline.split("\t")[1] == self.ID.strip()): - alreadythere = True - break - f.close() - except: - pass - if (not(alreadythere)): - f = open("downloadwatch", "a") - f.write("DOCK\t" + self.ID.strip() + "\t" + str(datetime.datetime.now().strftime("%A, %B %d - %I:%M:%S %p")) + "\t" + getServerName() + "\n") - f.close() - dlg = wx.MessageDialog(self, "InteractiveROSETTA is now watching the server for job ID " + self.ID.strip() + ". You will be notified when the package is available for download.", "Listening for Download", wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE) - dlg.ShowModal() - dlg.Destroy() - # Re-enable everything since we're not waiting for the local daemon to do anything - self.viewMenu.Disable() - self.parent.GoBtn.Enable() - self.btnAddStatic.Enable() - self.btnRemoveStatic.Enable() - self.btnAddMoving.Enable() - self.btnRemoveMoving.Enable() - self.btnStarting.Enable() - if (platform.system() == "Darwin"): - self.btnDock.SetBitmapLabel(bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnDock.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap()) - else: - self.btnDock.SetLabel("Dock!") - self.buttonState = "Dock!" - self.btnDock.SetToolTipString("Perform docking simulation with selected parameters") - self.seqWin.cannotDelete = False - # Pop this message out of the queue - for i in range(0, len(self.seqWin.msgQueue)): - if (self.seqWin.msgQueue[i].find("Performing protein docking") >= 0): - self.seqWin.msgQueue.pop(i) - break - if (len(self.seqWin.msgQueue) > 0): - self.seqWin.labelMsg.SetLabel(self.seqWin.msgQueue[len(self.seqWin.msgQueue)-1]) - else: - self.seqWin.labelMsg.SetLabel("") - logInfo("Coarse docking input sent to server daemon with ID " + self.ID) - return - except: - dlg = wx.MessageDialog(self, "The server could not be reached! Ensure that you have specified a valid server and that you have an network connection.", "Server Could Not Be Reached", wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE) - dlg.ShowModal() - dlg.Destroy() - return + f.write("RECEPTOR\t" + self.receptorChains + "\n") + f.write("PEPTIDE\t" + self.peptideChain + "\n") + f.write("DECOYS\t" + self.txtDecoys.GetValue() + "\n") + f.write("RETURNMODELS\t" + self.txtReturn.GetValue() + "\n") + if (self.movingChains[0] == "flexpeptide|P"): + f.write("FLEXMODE\tABINITIO\n") else: - os.rename("coarsedockinputtemp", "coarsedockinput") - self.usingServer = False - logInfo("Coarse docking input uploaded locally at coarsedockinput") - self.stage = 2 - self.looptimecount = 0 - self.timeout = 180 - self.tmrDock.Start(1000) + f.write("FLEXMODE\tREFINED\n") + f.close() + appendScorefxnParamsInfoToFile("flexpepinputtemp", self.selectWin.weightsfile) + # Try to send it to the server try: - os.remove("dock_progress") - except: - pass - self.progress = wx.ProgressDialog("Coarse Docking", "Performing coarse protein docking...", int(self.txtCoarse.GetValue()), style=wx.PD_CAN_ABORT | wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME | wx.PD_REMAINING_TIME) - elif (self.stage == 2): - # This is really annoying, here's the ugly memory problem again - # So first we have to do a coarse KIC job in the daemon - # This involves using centroid residues, so those have to be repacked in another - # instance of the daemon process because the repacking step pushes the memory usage too - # high, so first wait for the "repackmetemp.pdb" structure to show up, kill the daemon - # and restart it to do the repacking step - if (os.path.isfile("repackmedocktemp_" + str(int(self.txtRefined.GetValue())-1) + ".pdb")): - self.tmrDock.Stop() - try: - self.progress.Destroy() - except: - pass - # Pop this message out of the queue - for i in range(0, len(self.seqWin.msgQueue)): - if (self.seqWin.msgQueue[i].find("Performing protein docking") >= 0): - self.seqWin.msgQueue.pop(i) - break - self.seqWin.labelMsg.SetLabel("Performing rotamer repacking, please be patient...") - self.seqWin.labelMsg.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.BOLD)) - self.seqWin.labelMsg.SetForegroundColour("#FFFFFF") - self.seqWin.msgQueue.append("Performing rotamer repacking, please be patient...") - self.parent.parent.restartDaemon() - for i in range(0, int(self.txtRefined.GetValue())): - os.rename("repackmedocktemp_" + str(i) + ".pdb", "repackmedock_" + str(i) + ".pdb") # So the new daemon sees it - logInfo("repackmedocktemp.pdb sent to be rotamer repacked") - self.stage = 3 - self.tmrDock.Start(1000) - elif (os.path.isfile("errreport")): - # Something went wrong, tell the user about it (loop sequence probably too short) - self.tmrDock.Stop() + self.ID = sendToServer("flexpepinput") + # First make sure this isn't a duplicate + alreadythere = False try: - self.progress.Destroy() + f = open("downloadwatch", "r") + for aline in f: + if (len(aline.split("\t")) >= 2 and aline.split("\t")[0] == "FLEXPEP" and aline.split("\t")[1] == self.ID.strip()): + alreadythere = True + break + f.close() except: pass - self.parent.parent.restartDaemon() # Has to happen because coarse KIC is threaded - self.recoverFromError() - elif (os.path.isfile("dock_progress")): - f = open("dock_progress", "r") - for aline in f: - count = int(aline) - f.close() - if (count == int(self.txtCoarse.GetValue())): - try: - self.progress.Destroy() - except: - pass - else: - (keepGoing, skip) = self.progress.Update(count) - if (not(keepGoing)): - # User clicked "Cancel" on the progress bar - self.cancelDock() - self.progress.Destroy() - elif (self.stage == 3): - # Now we have to wait for the output of the repacking step and restart the daemon again - # so we can finish up with a fine-grained KIC step - if (os.path.isfile("repackeddock_" + str(int(self.txtRefined.GetValue())-1) + ".pdb")): - self.tmrDock.Stop() - # Pop this message out of the queue - for i in range(0, len(self.seqWin.msgQueue)): - if (self.seqWin.msgQueue[i].find("Performing rotamer repacking") >= 0): - self.seqWin.msgQueue.pop(i) - break - self.seqWin.labelMsg.SetLabel("Performing refined protein docking, please be patient...") - self.seqWin.labelMsg.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.BOLD)) - self.seqWin.labelMsg.SetForegroundColour("#FFFFFF") - self.seqWin.msgQueue.append("Performing refined protein docking, please be patient...") - self.parent.parent.restartDaemon() - os.rename("finedockinputtemp", "finedockinput") # So the new daemon sees it - logInfo("Repacked coarse structure sent to fine grained docking") - self.stage = 4 - self.tmrDock.Start(1000) - elif (os.path.isfile("errreport")): - # Something went wrong, tell the user about it - self.tmrDock.Stop() - self.recoverFromError() - elif (self.stage == 4): - if (self.usingServer): - # See if the file has been uploaded yet and bring it here if so - queryServerForResults("dockoutput-" + self.ID) - queryServerForResults("coarsedockoutput-" + self.ID) - self.timeoutCount = self.timeoutCount + 1 - if (self.timeoutCount >= serverTimeout): - self.tmrDock.Stop() - # If this is taking too long, maybe there's something wrong with the server - # Ask the user if they want to continue waiting or use the local daemon instead - dlg = wx.MessageDialog(self, "The server is taking a long time to respond. Continue to wait? Pressing No will run the calculations locally.", "Delayed Server Response", wx.YES_NO | wx.ICON_EXCLAMATION | wx.CENTRE) - if (dlg.ShowModal() == wx.ID_YES): - # Reset the counter - self.timeoutCount = 0 - else: - self.usingServer = False - self.timeoutCount = 0 - os.rename("coarsedockinputtemp", "coarsedockinput") - logInfo("Server took too long to respond so the local daemon was used") - self.stage = 2 + if (not(alreadythere)): + f = open("downloadwatch", "a") + f.write("FLEXPEP\t" + self.ID.strip() + "\t" + str(datetime.datetime.now().strftime("%A, %B %d - %I:%M:%S %p")) + "\t" + getServerName() + "\n") + f.close() + dlg = wx.MessageDialog(self, "InteractiveROSETTA is now watching the server for job ID " + self.ID.strip() + ". You will be notified when the package is available for download.", "Listening for Download", wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE) + dlg.ShowModal() dlg.Destroy() - self.tmrDock.Start(1000) - # Read the output dumped by the child process (finally!) - if (os.path.isfile("repackeddocktemp.pdb")): - # Flip back so the timer sees repacked.pdb and runs the local daemon - os.rename("coarsedockinputtemp", "finedockinputtemp") - os.rename("repackeddocktemp.pdb", "repackeddock.pdb") - # Pop this message out of the queue - for i in range(0, len(self.seqWin.msgQueue)): - if (self.seqWin.msgQueue[i].find("Performing protein docking") >= 0): - self.seqWin.msgQueue.pop(i) - break - self.usingServer = False - self.timeoutCount = 0 - self.stage = 3 - elif (os.path.isfile("dockoutput")): - self.tmrDock.Stop() - self.residue_E = [] - self.dockmodels = [] - f = open("dockoutput", "r") - for aline in f: - if (aline[0:6] == "OUTPUT"): - pdbfile = aline.split("\t")[1].strip() - self.dockmodels.append(pdbfile) - self.residue_E.append([]) - #self.dockView = pose_from_pdb(pdbfile) - elif (aline[0:6] == "ENERGY"): - if (aline.split()[1] == "total_score"): - # This is the scoretype line, row 0 in residue_E - self.residue_E[len(self.residue_E)-1].append(aline.split()[1:]) - else: - self.residue_E[len(self.residue_E)-1].append([]) - indx = len(self.residue_E[len(self.residue_E)-1]) - 1 - for E in aline.split()[1:]: - self.residue_E[len(self.residue_E)-1][indx].append(float(E)) - f.close() - self.dockView = self.seqWin.pdbreader.get_structure("dock_view", self.dockmodels[0]) - self.selectedModel = self.dockmodels[0] - logInfo("Found docking output at dockoutput") - # Pop this message out of the queue - for i in range(0, len(self.seqWin.msgQueue)): - if (self.seqWin.msgQueue[i].find("Performing refined protein docking") >= 0): - self.seqWin.msgQueue.pop(i) - break - if (len(self.seqWin.msgQueue) > 0): - self.seqWin.labelMsg.SetLabel(self.seqWin.msgQueue[len(self.seqWin.msgQueue)-1]) - else: - self.seqWin.labelMsg.SetLabel("") - self.seqWin.labelMsg.SetFont(wx.Font(10, wx.DEFAULT, wx.ITALIC, wx.BOLD)) - self.seqWin.labelMsg.SetForegroundColour("#FFFFFF") - # Add these loop residues to the view menu so the user can look at the new loop - self.viewMenu.Clear() - self.viewMenu.AppendItems(self.dockmodels) - self.viewMenu.SetSelection(0) - self.viewMenu.Enable() - self.parent.GoBtn.Enable() - self.btnDock.Enable() - #self.btnSave.Enable() - #self.enableControls() - #self.selectedModel = "" - if (platform.system() == "Darwin"): - self.btnDock.SetBitmapLabel(bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnDock_Finalize.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap()) - else: - self.btnDock.SetLabel("Finalize!") - self.buttonState = "Finalize!" - self.btnDock.SetToolTipString("Accept or reject protocol results") - os.remove("dockoutput") - # Load the docked pose as the "dock_view" model so the user can look at the results - self.cmd.load(self.dockmodels[0], "dock_view") - self.cmd.hide("everything", "model dock_view") - #recolorEnergies(self.dockView, self.residue_E[0], "dock_view", self.scoretypeMenu.GetStringSelection(), self.cmd) - self.focusView(self.viewMenu.GetStringSelection(), "dock_view") - elif (os.path.isfile("errreport")): - # Something went wrong, tell the user about it - self.tmrDock.Stop() - self.recoverFromError() \ No newline at end of file + except: + dlg = wx.MessageDialog(self, "The flexible peptide docking job could not be sent to the server! Verify that you have an Internet connection and that the server is running.", "Server Could Not Be Reached", wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE) + dlg.ShowModal() + dlg.Destroy() \ No newline at end of file diff --git a/InteractiveROSETTA/scripts/kic.py b/InteractiveROSETTA/scripts/kic.py index be3d819..23a8bc6 100644 --- a/InteractiveROSETTA/scripts/kic.py +++ b/InteractiveROSETTA/scripts/kic.py @@ -7,6 +7,7 @@ import platform import multiprocessing import webbrowser +import datetime from threading import Thread from tools import * @@ -643,13 +644,16 @@ def add(self, event): return # If we're doing a de novo search, is the sequence specified? if (self.loopType == "De Novo"): - for AA in self.txtSequence.GetValue().strip().upper(): + sequence = self.txtSequence.GetValue().strip().upper() + for AA in sequence: if (not(AA in "ACDEFGHIKLMNPQRSTVWY")): wx.MessageBox("The sequence you have provided is invalid. Please only use canonical amino acids.", "Sequence Invalid", wx.OK|wx.ICON_EXCLAMATION) return - if (len(self.txtSequence.GetValue().strip().upper()) == 0): + if (len(sequence) == 0): wx.MessageBox("You have indicated that you want to design a loop de novo but have not provided the putative sequence of the loop. Please provide one or switch to use a pre-existing loop.", "No Sequence Indicated", wx.OK|wx.ICON_EXCLAMATION) return + else: + sequence = "" # Did the model change? If yes, and loops is not empty, then tell the user that this # will remove all loops to make room for the new model if (len(self.loops) > 0 and self.modelMenu.GetValue() != self.loops[0][2]): @@ -660,7 +664,7 @@ def add(self, event): self.loops = [] # Does this loop overlap with a previously-specified loop? If so, do not add i = 1 - for loopType, sequence, model, begin, pivot, end in self.loops: + for loopType, s, model, begin, pivot, end in self.loops: if ((self.loopBegin >= begin and self.loopBegin <= end) or (self.loopEnd >= begin and self.loopEnd <= end)): dlg = wx.MessageDialog(self, "The loop you have indicated overlaps with loop " + str(i) + ". Either change the current loop or remove loop " + str(i) + ".", "Loop Overlap", wx.OK | wx.ICON_ERROR | wx.CENTRE) dlg.ShowModal() @@ -668,7 +672,7 @@ def add(self, event): return i += 1 # Add this loop to the list of loops currently active - self.loops.append([self.loopType, self.txtSequence.GetValue().strip().upper(), self.modelMenu.GetValue(), self.loopBegin, self.menuPivot.GetSelection() + self.loopBegin, self.loopEnd]) + self.loops.append([self.loopType, sequence, self.modelMenu.GetValue(), self.loopBegin, self.menuPivot.GetSelection() + self.loopBegin, self.loopEnd]) self.updateLoops() def remove(self, event): @@ -864,21 +868,9 @@ def KICClick(self, event): # This is also the "Finalize!" button if (self.buttonState == "KIC!"): # First we have to make sure that the loops are defined and that the sequence is valid - if (self.loopBegin < 0): - wx.MessageBox("Please select a loop beginning position.", "Loop Begin Required", wx.OK|wx.ICON_EXCLAMATION) - return - elif (self.loopEnd < 0): - wx.MessageBox("Please select a loop ending position.", "Loop End Required", wx.OK|wx.ICON_EXCLAMATION) + if (len(self.loops) == 0): + wx.MessageBox("Please specify at least one valid loop to model", "No Loops Provided", wx.OK|wx.ICON_EXCLAMATION) return - elif (self.loopType == "De Novo"): - # Make sure the sequence has only CAAs in it - for AA in self.txtSequence.GetValue().strip().upper(): - if (not(AA in "ACDEFGHIKLMNPQRSTVWY")): - wx.MessageBox("The sequence you have provided is invalid. Please only use canonical amino acids.", "Sequence Invalid", wx.OK|wx.ICON_EXCLAMATION) - return - if (len(self.txtSequence.GetValue().strip().upper()) == 0): - wx.MessageBox("You have indicated that you want to design a loop de novo but have not provided the putative sequence of the loop. Please provide one or switch to use a pre-existing loop.", "No Sequence Indicated", wx.OK|wx.ICON_EXCLAMATION) - return try: if (int(self.txtNStruct.GetValue()) <= 0): raise Exception @@ -1063,44 +1055,92 @@ def threadKIC(self, event): f.write(aline.strip() + "\n") f.write("END PDB DATA\n") f2.close() - f.write("REMODEL\t" + self.loopType.upper() + "\n") - chain = self.beginMenu.GetStringSelection()[0] - seqpos = self.beginMenu.GetStringSelection()[3:] - loopBegin = self.seqWin.getRosettaIndex(self.selectedModel, chain, seqpos) - f.write("LOOPBEGIN\t" + str(loopBegin) + "\n") - chain = self.endMenu.GetStringSelection()[0] - seqpos = self.endMenu.GetStringSelection()[3:] - loopEnd = self.seqWin.getRosettaIndex(self.selectedModel, chain, seqpos) - f.write("LOOPEND\t" + str(loopEnd) + "\n") - if (self.loopType == "De Novo"): - f.write("SEQUENCE\t" + self.txtSequence.GetValue().strip().upper() + "\n") - f.write("PIVOT\t" + str(self.menuPivot.GetSelection()) + "\n") + #f.write("REMODEL\t" + self.loopType.upper() + "\n") + #chain = self.beginMenu.GetStringSelection()[0] + #seqpos = self.beginMenu.GetStringSelection()[3:] + #loopBegin = self.seqWin.getRosettaIndex(self.selectedModel, chain, seqpos) + #f.write("LOOPBEGIN\t" + str(loopBegin) + "\n") + #chain = self.endMenu.GetStringSelection()[0] + #seqpos = self.endMenu.GetStringSelection()[3:] + #loopEnd = self.seqWin.getRosettaIndex(self.selectedModel, chain, seqpos) + #f.write("LOOPEND\t" + str(loopEnd) + "\n") + #if (self.loopType == "De Novo"): + #f.write("SEQUENCE\t" + self.txtSequence.GetValue().strip().upper() + "\n") + #f.write("PIVOT\t" + str(self.menuPivot.GetSelection()) + "\n") + # Write the loops information + for [loopType, sequence, model, begin, pivot, end] in self.loops: + f.write("LOOP\t" + loopType.upper() + "\t" + sequence.strip() + "\t" + str(begin) + "\t" + str(pivot) + "\t" + str(end) + "\n") f.write("NSTRUCT\t" + str(self.nstruct) + "\n") f.write("PERTURB\t" + self.perturbType + "\n") - f.write("OUTPUTDIR\t" + self.outputdir + "\n") + #f.write("OUTPUTDIR\t" + self.outputdir + "\n") f.close() appendScorefxnParamsInfoToFile("coarsekicinputtemp", self.selectWin.weightsfile) - if (False): #(useServer): + if (self.serverOn): try: self.ID = sendToServer("coarsekicinput") - self.usingServer = True + # First make sure this isn't a duplicate + alreadythere = False + try: + f = open("downloadwatch", "r") + for aline in f: + if (len(aline.split("\t")) >= 2 and aline.split("\t")[0] == "KIC" and aline.split("\t")[1] == self.ID.strip()): + alreadythere = True + break + f.close() + except: + pass + if (not(alreadythere)): + f = open("downloadwatch", "a") + f.write("KIC\t" + self.ID.strip() + "\t" + str(datetime.datetime.now().strftime("%A, %B %d - %I:%M:%S %p")) + "\t" + getServerName() + "\n") + f.close() + dlg = wx.MessageDialog(self, "InteractiveROSETTA is now watching the server for job ID " + self.ID.strip() + ". You will be notified when the package is available for download.", "Listening for Download", wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE) + dlg.ShowModal() + dlg.Destroy() + # Re-enable everything since we're not waiting for the local daemon to do anything + self.scoretypeMenu.Disable() + self.viewMenu.Disable() + self.modelMenu.Enable() + self.beginMenu.Enable() + self.endMenu.Enable() + self.btnLoopType.Enable() + if (self.loopType == "De Novo"): + self.txtSequence.Enable() + if (platform.system() == "Darwin"): + self.btnKIC.SetBitmapLabel(bitmap=wx.Image(self.parent.parent.scriptdir + "/images/osx/btnKIC.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap()) + else: + self.btnKIC.SetLabel("KIC!") + self.buttonState = "KIC!" + self.btnKIC.SetToolTipString("Perform KIC simulation with selected parameters") + self.cmd.label("all", "") + self.seqWin.cannotDelete = False + # Pop this message out of the queue + for i in range(0, len(self.seqWin.msgQueue)): + if (self.seqWin.msgQueue[i].find("Performing KIC loop modeling") >= 0): + self.seqWin.msgQueue.pop(i) + break + if (len(self.seqWin.msgQueue) > 0): + self.seqWin.labelMsg.SetLabel(self.seqWin.msgQueue[len(self.seqWin.msgQueue)-1]) + else: + self.seqWin.labelMsg.SetLabel("") logInfo("Coarse KIC input sent to server daemon with ID " + self.ID) - self.stage = 4 # When using server we cannot see the intermediates + return except: - # Something failed, default to the local daemon - os.rename("coarsekicinputtemp", "coarsekicinput") - self.usingServer = False - logInfo("Server daemon not available, coarse KIC input uploaded at coarsekicinput") - self.stage = 2 + dlg = wx.MessageDialog(self, "The server could not be reached! Ensure that you have specified a valid server and that you have an network connection.", "Server Could Not Be Reached", wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE) + dlg.ShowModal() + dlg.Destroy() + return else: os.rename("coarsekicinputtemp", "coarsekicinput") self.usingServer = False logInfo("Coarse KIC input uploaded locally at coarsekicinput") self.stage = 2 - if (self.perturbType == "Perturb Only, Centroid" or self.loopType == "Refine"): + if (self.perturbType == "Perturb Only, Centroid"):# or self.loopType == "Refine"): self.stage = 4 self.looptimecount = 0 self.timeout = 18000000 + self.progress = wx.ProgressDialog("KIC Progress", "Modeling loops in centroid mode...", 100, style=wx.PD_CAN_ABORT | wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME | wx.PD_REMAINING_TIME) + self.loop_indx = 0 + self.last_progress_indx = 99 self.tmrKIC.Start(1000) elif (self.stage == 2): # This is really annoying, here's the ugly memory problem again @@ -1205,6 +1245,10 @@ def threadKIC(self, event): self.stage = 3 elif (os.path.isfile("kicoutput")): self.tmrKIC.Stop() + try: + self.progress.Destroy() + except: + pass self.residue_E = [] f = open("kicoutput", "r") for aline in f: @@ -1286,7 +1330,57 @@ def threadKIC(self, event): self.seqWin.pdbwriter.set_structure(self.KICView) self.seqWin.pdbwriter.save(pdbfile) recolorEnergies(self.KICView, self.residue_E, "kic_view", self.scoretypeMenu.GetStringSelection(), self.cmd) + return elif (os.path.isfile("errreport")): # Something went wrong, tell the user about it + try: + self.progress.Destroy() + except: + pass self.tmrKIC.Stop() - self.recoverFromError() \ No newline at end of file + self.recoverFromError() + return + if (os.path.isfile("scanprogress")): + f = open("scanprogress", "r") + data = f.readlines() + f.close() + if (len(data) == 0): + return + try: + lastline = None + for j in range(len(data)-1, -1, -1): + if (data[j].strip().startswith("protocols.loops.loop_mover.refine.LoopMover_Refine_KIC: refinement cycle")): + lastline = data[j].strip() + break + if (lastline is None): + raise Exception() + outercycles = lastline.split()[len(lastline.split())-2] + innercycles = lastline.split()[len(lastline.split())-1] + outer_num = int(outercycles.split("/")[0]) + outer_den = int(outercycles.split("/")[1]) + inner_num = int(innercycles.split("/")[0]) + inner_den = int(innercycles.split("/")[1]) + maxtrials = outer_den * inner_den + currpos = (outer_num-1) * inner_den + inner_num + indx = int(currpos * 100.0 / maxtrials) + if (indx >= 100): + # This should be destroyed when the refined KIC output is available + indx = 99 + except: + return + if (indx >= 100): + try: + self.progress.Destroy() + except: + pass + else: + if (self.last_progress_indx > indx): + self.loop_indx += 1 + (keepGoing, skip) = self.progress.Update(indx, "Refining loop " + str(self.loop_indx) + " in fullatom mode...") + else: + (keepGoing, skip) = self.progress.Update(indx) + self.last_progress_indx = indx + if (not(keepGoing)): + # User clicked "Cancel" on the progress bar + self.cancelKIC() + self.progress.Destroy() \ No newline at end of file diff --git a/InteractiveROSETTA/scripts/pointmutations.py b/InteractiveROSETTA/scripts/pointmutations.py index b076adc..cbc01e8 100644 --- a/InteractiveROSETTA/scripts/pointmutations.py +++ b/InteractiveROSETTA/scripts/pointmutations.py @@ -921,6 +921,7 @@ def threadScore(self, event): f = open("scoreinputtemp", "w") pdbfile = self.selectedModel + ".pdb" # Dump the PDB from PyMOL first in case the coordinates were altered by the user + self.scoreModel = self.selectedModel self.cmd.save(pdbfile.strip(), "model " + self.selectedModel) fixPyMOLSave(pdbfile.strip()) f.write("PDBFILE\t" + pdbfile.strip() + "\n") @@ -1033,6 +1034,12 @@ def threadScore(self, event): self.grdEnergies.SetRowAttr(i, readOnly) self.parent.GoBtn.Enable() self.btnSearch.Enable() + self.cmd.remove(self.scoreModel) + self.cmd.delete(self.scoreModel) + self.cmd.load(self.scoreModel + "_S.pdb", self.scoreModel) + poseindx = self.seqWin.getPoseIndexForModel(self.scoreModel) + self.seqWin.reloadPose(poseindx, self.scoreModel, self.scoreModel + "_S.pdb") + defaultPyMOLView(self.cmd, self.scoreModel) self.energiesCalculated = True self.recolorEnergies() self.seqWin.recolorResidues() diff --git a/InteractiveROSETTA/scripts/protocols.py b/InteractiveROSETTA/scripts/protocols.py index cf53c8f..5fde65e 100644 --- a/InteractiveROSETTA/scripts/protocols.py +++ b/InteractiveROSETTA/scripts/protocols.py @@ -37,6 +37,7 @@ from surfaces import SurfacesPanel from antibody import AntibodyPanel from ensemblegen import EnsembleGenPanel +from flexpepdock import FlexPepDockPanel class ProtocolsPanel(wx.Panel): def __init__(self, parent, W, H): @@ -63,6 +64,7 @@ def __init__(self, parent, W, H): "Energy Minimization", "Ensemble Browser", "Ensemble Generation", + "Flexible Peptide Docking", "Loop Modeling (KIC)", "Molecular Surfaces", "Point Mutant Scan", @@ -252,6 +254,9 @@ def changeProtocol(self, event): self.parent.Selection.displaySurfaces() self.protPanel.Destroy() del self.protPanel + elif (self.currentProtocol == "Flexible Peptide Docking"): + self.protPanel.Destroy() + del self.protPanel self.currentProtocol = selectedProtocol self.seqWin.cannotDelete = False # Restart the Rosetta daemon to clear its memory up @@ -295,6 +300,9 @@ def changeProtocol(self, event): elif (selectedProtocol == "Molecular Surfaces"): self.protPanel = SurfacesPanel(self, self.W, self.H) self.cmd.hide("surface", "all") + elif (selectedProtocol == "Flexible Peptide Docking"): + self.protPanel = FlexPepDockPanel(self, self.W, self.H) + self.protPanel.setSelectWin(self.selectWin) self.protPanel.setSeqWin(self.seqWin) self.protPanel.setPyMOL(self.pymol) self.protPanel.activate() diff --git a/InteractiveROSETTA/scripts/residuecreator.py b/InteractiveROSETTA/scripts/residuecreator.py index 628e096..c9a79c1 100644 --- a/InteractiveROSETTA/scripts/residuecreator.py +++ b/InteractiveROSETTA/scripts/residuecreator.py @@ -501,6 +501,7 @@ def addToDB(self, event): self.typeMenu.Clear() self.btnAdd.Disable() self.removeMenu.Append(self.selectedType) + self.cmd.remove("params") def removeParams(self, event): # Take the indicated parameters file out of the database diff --git a/InteractiveROSETTA/scripts/selection.py b/InteractiveROSETTA/scripts/selection.py index c9c3515..8ef4b7f 100644 --- a/InteractiveROSETTA/scripts/selection.py +++ b/InteractiveROSETTA/scripts/selection.py @@ -1196,7 +1196,7 @@ def selectInvert(self, event): logInfo("Inverted current selection") def selectVisible(self, event): - self.cmd.select("seqsele", "visible") + self.cmd.select("seqsele", "rep lines or rep sticks or rep spheres") self.cmd.enable("seqsele") self.seqWin.selectUpdate(False) logInfo("Clicked on the visible select button") diff --git a/InteractiveROSETTA/scripts/sequence.py b/InteractiveROSETTA/scripts/sequence.py index d65866a..e0d6d46 100644 --- a/InteractiveROSETTA/scripts/sequence.py +++ b/InteractiveROSETTA/scripts/sequence.py @@ -661,7 +661,8 @@ def __init__(self, W, H, cwd, frozen, poses, sequences, IDs, scriptdir): self.Bind(wx.grid.EVT_GRID_CELL_RIGHT_CLICK, self.rightClick) self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_DCLICK, self.labelDClick) self.Bind(wx.grid.EVT_GRID_LABEL_RIGHT_CLICK, self.labelRClick) - self.SeqViewer.GetGridWindow().Bind(wx.EVT_KEY_DOWN, self.keyPress) + self.Bind(wx.EVT_CHAR_HOOK, self.keyPress) + #self.SeqViewer.GetGridWindow().Bind(wx.EVT_KEY_DOWN, self.keyPress) self.selectedResidues = [] # This is the label along the bottom of the window, that displays what Rosetta is currently doing @@ -986,11 +987,12 @@ def keyPress(self, event): currID = currID + fields[i] + "|" currID = currID[0:len(currID)-1] chainID = fields[len(fields)-1] - if (chainID != "_"): - self.cmd.remove("model " + currID + " and chain " + chainID + " and resi " + str(pyMOLPos)) - else: - self.cmd.remove("model " + currID + " and resi " + str(pyMOLPos)) + #if (chainID != "_"): + # self.cmd.remove("model " + currID + " and chain " + chainID + " and resi " + str(pyMOLPos)) + #else: + # self.cmd.remove("model " + currID + " and resi " + str(pyMOLPos)) # Now delete whole chains that we may have identified + self.cmd.remove("byres seqsele") for i in range(len(chain_deletes)-1, -1, -1): self.deleteChain(chain_deletes[i]) #self.recolorResidues() @@ -1015,7 +1017,7 @@ def keyPress(self, event): self.SeqViewer.ClearSelection() self.PyMOLUpdateTimer.Stop() self.PyMOLUpdateTimer.Start(100) - elif (event.ControlDown() and int(event.GetKeyCode()) == ord("C")): + elif (event.ControlDown() and int(event.GetKeyCode()) == 3): # Copy the current selection to the clipboard as FASTA data copystr = "" amISelected = [] @@ -1024,11 +1026,13 @@ def keyPress(self, event): for c in range(0, len(self.sequences[r])): amISelected[r].append(0) # Find the selections - for data in self.getSelectedResidues(): - r = data[0] - for c in data[2]: - if (c < len(amISelected[r])): - amISelected[r][c] = 1 + topLefts = self.SeqViewer.GetSelectionBlockTopLeft() + bottomRights = self.SeqViewer.GetSelectionBlockBottomRight() + for i in range(0, len(topLefts)): + for r in range(topLefts[i][0], bottomRights[i][0]+1): + for c in range(topLefts[i][1], bottomRights[i][1]+1): + if (c < len(amISelected[r])): + amISelected[r][c] = 1 # Do the copying for r in range(0, len(self.sequences)): if (sum(amISelected[r]) > 0): @@ -1938,7 +1942,10 @@ def fetchClick(self, event): # pdbfile is the filename to load # showDialog is "Show" if the protein load dialog should be shown # showDialog should be "Reuse" for extra models in an ensemble pdbfile - def PyMOLPDBLoad(self, dummy, pdbfile, showDialog="NoShow"): + # FlexiblePeptide is specific for when FlexPepDock attempts to create the peptide + # Usually the name "flexpeptide" is reserved but this tells the loader to use the + # flexpeptide keyword for this peptide + def PyMOLPDBLoad(self, dummy, pdbfile, showDialog="NoShow", flexiblePeptide=False): pdbfile = str(pdbfile) # Check the PDB for duplicate atoms # We want to rename dupliates otherwise BioPython will drop them @@ -1988,7 +1995,9 @@ def PyMOLPDBLoad(self, dummy, pdbfile, showDialog="NoShow"): break # Sometimes I use special names for selections, and if the modelname is the same as # these selections it can screw things up - if (newID in ["temp", "sele", "seqsele"]): + if (newID in ["temp", "sele", "seqsele", "params", "designed_view", "minimized_view"]): + taken = True + if (newID == "flexpeptide" and not(flexiblePeptide)): taken = True # Replace whitespace with _ to avoid PyMOL issues newID = newID.replace(" ", "_") @@ -3141,7 +3150,7 @@ def downloader(self, event): except: # Not there yet pass - elif (job.startswith("MSD") or job.startswith("ANTIBODY") or job.startswith("DOCK") or job.startswith("PMUTSCAN") or job.startswith("BACKRUB")): + elif (job.startswith("MSD") or job.startswith("ANTIBODY") or job.startswith("DOCK") or job.startswith("PMUTSCAN") or job.startswith("BACKRUB") or job.startswith("KIC") or job.startswith("FLEXPEP")): jobtype = job.split("\t")[0] ID = job.split("\t")[1].strip() jobURL = job.split("\t")[3].strip() @@ -3176,6 +3185,10 @@ def downloader(self, event): dlg = wx.MessageDialog(self, "Your point mutant scanning job ID " + ID + " is ready.", "Point Mutants Ready", wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE) elif (jobtype == "BACKRUB"): dlg = wx.MessageDialog(self, "Your backrub ensemble job ID " + ID + " is ready.", "Backrub Ensemble Ready", wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE) + elif (jobtype == "KIC"): + dlg = wx.MessageDialog(self, "Your KIC ensemble job ID " + ID + " is ready.", "KIC Ensemble Ready", wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE) + elif (jobtype == "FLEXPEP"): + dlg = wx.MessageDialog(self, "Your flexible peptide docking package job ID " + ID + " is ready.", "Flexible Peptide Docking Ready", wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE) dlg.ShowModal() dlg.Destroy() os.rename(filepath, "results" + packageext) @@ -3192,6 +3205,10 @@ def downloader(self, event): dlg = wx.MessageDialog(self, "Your point mutant scanning job ID " + ID + " is ready.", "Point Mutants Download Ready", wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE) elif (jobtype == "BACKRUB"): dlg = wx.MessageDialog(self, "Your backrub ensemble job ID " + ID + " is ready.", "Backrub Ensemble Download Ready", wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE) + elif (jobtype == "KIC"): + dlg = wx.MessageDialog(self, "Your KIC ensemble job ID " + ID + " is ready.", "KIC Ensemble Download Ready", wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE) + elif (jobtype == "FLEXPEP"): + dlg = wx.MessageDialog(self, "Your flexible peptide docking package job ID " + ID + " is ready.", "Flexible Peptide Docking Download Ready", wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE) dlg.ShowModal() dlg.Destroy() if (jobtype == "MSD"): @@ -3204,6 +3221,10 @@ def downloader(self, event): busyDlg = wx.BusyInfo("Downloading point mutant scan report, please wait...") elif (jobtype == "BACKRUB"): busyDlg = wx.BusyInfo("Downloading backrub archive, please wait...") + elif (jobtype == "KIC"): + busyDlg = wx.BusyInfo("Downloading KIC archive, please wait...") + elif (jobtype == "FLEXPEP"): + busyDlg = wx.BusyInfo("Downloading flexpep archive, please wait...") (oldfilename, info) = urllib.urlretrieve(URL, "results" + packageext) busyDlg.Destroy() del busyDlg @@ -3243,6 +3264,20 @@ def downloader(self, event): defaultFile=ID, wildcard="Ensemble Archives (*.ensb)|*.ensb", style=wx.SAVE | wx.CHANGE_DIR) + elif (jobtype == "KIC"): + dlg = wx.FileDialog( + self, message="Save the KIC package", + defaultDir=self.cwd, + defaultFile=ID, + wildcard="Ensemble Archives (*.ensb)|*.ensb", + style=wx.SAVE | wx.CHANGE_DIR) + elif (jobtype == "FLEXPEP"): + dlg = wx.FileDialog( + self, message="Save the flexpep package", + defaultDir=self.cwd, + defaultFile=ID, + wildcard="Ensemble Archives (*.ensb)|*.ensb", + style=wx.SAVE | wx.CHANGE_DIR) if (dlg.ShowModal() == wx.ID_OK): if (platform.system() == "Darwin"): paths = [dlg.GetPath()] @@ -3281,7 +3316,7 @@ def downloader(self, event): f = open(self.cwd + "\\" + aline.split()[len(aline.split())-1].strip(), "w") else: f = open(self.cwd + "/" + aline.split()[len(aline.split())-1].strip(), "w") - elif (jobtype == "ANTIBODY" or jobtype == "DOCK" or jobtype == "BACKRUB"): + elif (jobtype == "ANTIBODY" or jobtype == "DOCK" or jobtype == "BACKRUB" or jobtype == "KIC" or jobtype == "FLEXPEP"): indx = aline[aline.rfind("_")+1:].strip() f = open(prefix + "_" + indx, "w") readingData = True diff --git a/InteractiveROSETTA/scripts/surfaces.py b/InteractiveROSETTA/scripts/surfaces.py index 7b7479e..1a7b8dd 100644 --- a/InteractiveROSETTA/scripts/surfaces.py +++ b/InteractiveROSETTA/scripts/surfaces.py @@ -285,9 +285,32 @@ def CPKColor(self, event): def elecColor(self, event): try: - self.cmd.set("surface_color", "white", "curr_surf_recp") - self.cmd.set("surface_color", "blue", "curr_surf_recp and (resn lys or resn arg)") - self.cmd.set("surface_color", "red", "curr_surf_recp and (resn asp or resn glu)") + total_charge = 0 + natoms = 0 + self.stored.bfactors = [] + self.cmd.iterate_state(1, "curr_surf_recp", "stored.bfactors.append([model, chain, resi, name, formal_charge])") + for model, chain, resi, name, c in self.stored.bfactors: + natoms += 1 + total_charge += c / 4 + if (len(chain.strip()) == 0): + chain = " " + selstring = "model " + model + " and resi " + str(resi) + " and name " + name + else: + selstring = "model " + model + " and chain " + chain + " and resi " + str(resi) + " and name " + name + if (c <= 0): + red = 255 + blue = int(255 * float(4+c)/4.0) + green = blue + else: + blue = 255 + red = int(255 * float(4-c)/4.0) + green = red + color = "0x%02x%02x%02x" % (red, green, blue) + self.cmd.set("surface_color", color, selstring) + if (total_charge < natoms / -2.0 or total_charge > natoms / 2): + self.cmd.set("surface_color", "white", "curr_surf_recp") + self.cmd.set("surface_color", "blue", "curr_surf_recp and (resn lys or resn arg)") + self.cmd.set("surface_color", "red", "curr_surf_recp and (resn asp or resn glu)") except: pass diff --git a/InteractiveROSETTA/server/cgi-bin/jobupload.cgi b/InteractiveROSETTA/server/cgi-bin/jobupload.cgi index 14051f0..e1be907 100755 --- a/InteractiveROSETTA/server/cgi-bin/jobupload.cgi +++ b/InteractiveROSETTA/server/cgi-bin/jobupload.cgi @@ -1,6 +1,7 @@ #!/usr/bin/python import sys import os +import commands iRosetta_home = ".." # Alter this if iRosetta home is not the parent directory of this script hostlist = iRosetta_home + "/hostlist" @@ -38,7 +39,7 @@ try: elif (aline.find("Content") < 0): filedata.append(aline.strip()) # Make sure the filename is something we'd be expecting to see from InteractiveROSETTA - if (not(filename in ["minimizeinput", "designinput", "scoreinput", "rotamerinput", "coarsekicinput", "msdinput", "testinput"])): + if (not(filename in ["minimizeinput", "designinput", "scoreinput", "rotamerinput", "coarsekicinput", "msdinput", "testinput", "coarsedockinput", "antibodyinput", "scaninput", "killinput", "backrubinput", "flexpepinput"])): raise Exception() if (filename == "testinput"): print "InteractiveROSETTA Upload Successful" diff --git a/InteractiveROSETTA/server/daemon_server.py b/InteractiveROSETTA/server/daemon_server.py index 653656a..78e5b13 100755 --- a/InteractiveROSETTA/server/daemon_server.py +++ b/InteractiveROSETTA/server/daemon_server.py @@ -654,7 +654,23 @@ def doRotamerSearch(inputfile): os.rename(hostname + "-rotameroutputtemp", "results/rotameroutput-" + ID) os.remove(weightsfile) -def doKIC(inputfile, stage="Coarse"): +def doKIC(inputfile): + # Make a new results folder and unpack the data there + try: + os.mkdir("results/" + ID) + except: + shutil.rmtree("results/" + ID, ignore_errors=True) + os.mkdir("results/" + ID) + os.chdir("results/" + ID) + # Move the input file here + os.rename("../../" + inputfile, inputfile.split("-")[1]) + # Submit it to the queue + sub = subprocess.Popen(["python", "../../rosetta_submit.py", "kic", ID]) + # The Python script will handle everything from here + # Get back to where we were + os.chdir("../..") + +def old_doKIC(inputfile, stage="Coarse"): try: f = open(inputfile, "r") except: @@ -914,6 +930,22 @@ def doBackrub(inputfile): # Get back to where we were os.chdir("../..") +def doFlexPep(inputfile): + # Make a new results folder and unpack the data there + try: + os.mkdir("results/" + ID) + except: + shutil.rmtree("results/" + ID, ignore_errors=True) + os.mkdir("results/" + ID) + os.chdir("results/" + ID) + # Move the input file here + os.rename("../../" + inputfile, inputfile.split("-")[1]) + # Submit it to the queue + sub = subprocess.Popen(["python", "../../rosetta_submit.py", "flexpep", ID]) + # The Python script will handle everything from here + # Get back to where we were + os.chdir("../..") + def writeError(msg, inputfile="None-"): # Open a file and write out the error message so the main GUI can tell the user what happened # The main GUI needs to check to see if an errreport gets generated and recover from the error @@ -989,86 +1021,92 @@ def writeError(msg, inputfile="None-"): # If the hostname has - in it, it will screw up the splitting later on, so fix it here os.rename(inputfile, "jobfiles/" + hostname.replace("-", "") + "-coarsekicinput-" + ID) inputfile = "jobfiles/" + hostname.replace("-", "") + "-coarsekicinput-" + ID - print "Daemon starting coarse KIC loop modeling job..." + print "Daemon starting KIC job..." + doKIC(inputfile) + #if ("-" in hostname): + # If the hostname has - in it, it will screw up the splitting later on, so fix it here + #os.rename(inputfile, "jobfiles/" + hostname.replace("-", "") + "-coarsekicinput-" + ID) + #inputfile = "jobfiles/" + hostname.replace("-", "") + "-coarsekicinput-" + ID + #print "Daemon starting coarse KIC loop modeling job..." # This is code to pipe stdout to a variable called "captured_stdout" so I can # parse the standard output of the coarse KIC perturber and see if it failed to # build the loop. Then I know the sequence was too short - stdout_fileno = sys.stdout.fileno() - stdout_save = os.dup(stdout_fileno) - stdout_pipe = os.pipe() - os.dup2(stdout_pipe[1], stdout_fileno) - os.close(stdout_pipe[1]) - captured_stdout = "" - t = Thread(target=drain_pipe) - t.start() - crashed = False - try: + #stdout_fileno = sys.stdout.fileno() + #stdout_save = os.dup(stdout_fileno) + #stdout_pipe = os.pipe() + #os.dup2(stdout_pipe[1], stdout_fileno) + #os.close(stdout_pipe[1]) + #captured_stdout = "" + #t = Thread(target=drain_pipe) + #t.start() + #crashed = False + #try: # This function call has the potential to run indefinitely if it cannot find # a way to bridge the two endpoint residues (in a de novo loop model) # The main GUI is timing the daemon's response though and will kill it and display # an error if it doesn't finish before a timeout (usually 3 min) - doKIC(inputfile, "Coarse") - os.rename(hostname + "-torepack.pdb", hostname + "-repackme.pdb") # So the GUI sees it - print "Daemon completed coarse KIC loop modeling job" - except Exception as e: - print "The daemon crashed while performing the coarse KIC loop modeling job!" - os.remove(inputfile) - writeError(e.message, inputfile) - crashed = True + #doKIC(inputfile, "Coarse") + #os.rename(hostname + "-torepack.pdb", hostname + "-repackme.pdb") # So the GUI sees it + #print "Daemon completed coarse KIC loop modeling job" + #except Exception as e: + #print "The daemon crashed while performing the coarse KIC loop modeling job!" + #os.remove(inputfile) + #writeError(e.message, inputfile) + #crashed = True # The daemon needs to be killed by the main GUI because the coarse KIC thread is # still running and will do so indefinitely # Clean up the thread that was reading the standard output - os.close(stdout_fileno) - t.join() + #os.close(stdout_fileno) + #t.join() # Clean up the pipe and restore the original stdout - os.close(stdout_pipe[0]) - os.dup2(stdout_save, stdout_fileno) - os.close(stdout_save) - outputline = captured_stdout.split("\n")[len(captured_stdout.split("\n"))-10] - try: - if (not(crashed) and outputline.find("Attempting loop building") >= 0 and int(outputline.split()[len(outputline.split())-2]) >= 100): - raise Exception("ERROR: The loop sequence is too short and cannot bridge the endpoint residues!") - except Exception as e: - print "The loop sequence was too short!" - os.remove(inputfile) - os.remove(hostname + "-repackme.pdb") - writeError(e.message, inputfile) - continue - if (crashed): - continue - print "Daemon starting rotamer repacking job..." - try: - doRepack(inputfile) - print "Daemon completed rotamer repacking job" - except Exception as e: - print "The daemon crashed while performing the rotamer repacking job!" - writeError(e.message, inputfile) - os.remove(inputfile) - os.remove("jobfiles/" + hostname + "-repackmetemp.pdb") - continue - if (doKICLocally): + #os.close(stdout_pipe[0]) + #os.dup2(stdout_save, stdout_fileno) + #os.close(stdout_save) + #outputline = captured_stdout.split("\n")[len(captured_stdout.split("\n"))-10] + #try: + #if (not(crashed) and outputline.find("Attempting loop building") >= 0 and int(outputline.split()[len(outputline.split())-2]) >= 100): + #raise Exception("ERROR: The loop sequence is too short and cannot bridge the endpoint residues!") + #except Exception as e: + #print "The loop sequence was too short!" + #os.remove(inputfile) + #os.remove(hostname + "-repackme.pdb") + #writeError(e.message, inputfile) + #continue + #if (crashed): + #continue + #print "Daemon starting rotamer repacking job..." + #try: + #doRepack(inputfile) + #print "Daemon completed rotamer repacking job" + #except Exception as e: + #print "The daemon crashed while performing the rotamer repacking job!" + #writeError(e.message, inputfile) + #os.remove(inputfile) + #os.remove("jobfiles/" + hostname + "-repackmetemp.pdb") + #continue + #if (doKICLocally): # Dump the repacked PDB file to an outputfile that the client can read - f = open(hostname + "-coarsekicoutputtemp", "w") - f2 = open(hostname + "-repacked.pdb", "r") - f.write("OUTPUT\trepackedtemp.pdb\n") - f.write("BEGIN PDB DATA\n") - for aline in f2: - f.write(aline.strip() + "\n") - f.write("END PDB DATA\n") - f2.close() - f.close() - os.rename(hostname + "-coarsekicoutputtemp", "results/coarsekicoutput-" + inputfile.split("-")[2]) - os.remove(hostname + "-repacked.pdb") - os.remove(inputfile) - else: - print "Daemon starting fine KIC loop modeling job..." - try: - doKIC(inputfile, "Fine") - print "Daemon completed fine KIC loop modeling job" - except Exception as e: - print "The daemon crashed while performing the fine KIC loop modeling job!" - writeError(e.message, inputfile) - os.remove(inputfile) + #f = open(hostname + "-coarsekicoutputtemp", "w") + #f2 = open(hostname + "-repacked.pdb", "r") + #f.write("OUTPUT\trepackedtemp.pdb\n") + #f.write("BEGIN PDB DATA\n") + #for aline in f2: + # f.write(aline.strip() + "\n") + #f.write("END PDB DATA\n") + #f2.close() + #f.close() + #os.rename(hostname + "-coarsekicoutputtemp", "results/coarsekicoutput-" + inputfile.split("-")[2]) + #os.remove(hostname + "-repacked.pdb") + #os.remove(inputfile) + #else: + #print "Daemon starting fine KIC loop modeling job..." + #try: + # doKIC(inputfile, "Fine") + # print "Daemon completed fine KIC loop modeling job" + #except Exception as e: + # print "The daemon crashed while performing the fine KIC loop modeling job!" + # writeError(e.message, inputfile) + #os.remove(inputfile) elif (inputfile.startswith("jobfiles/" + hostname + "-msdinput")): if ("-" in hostname): # If the hostname has - in it, it will screw up the splitting later on, so fix it here @@ -1105,6 +1143,13 @@ def writeError(msg, inputfile="None-"): inputfile = "jobfiles/" + hostname.replace("-", "") + "-backrubinput-" + ID print "Daemon starting backrubbing job..." doBackrub(inputfile) + elif (inputfile.startswith("jobfiles/" + hostname + "-flexpepinput")): + if ("-" in hostname): + # If the hostname has - in it, it will screw up the splitting later on, so fix it here + os.rename(inputfile, "jobfiles/" + hostname.replace("-", "") + "-flexpepinput-" + ID) + inputfile = "jobfiles/" + hostname.replace("-", "") + "-flexpepinput-" + ID + print "Daemon starting flexible peptide docking job..." + doFlexPep(inputfile) elif (inputfile.startswith("jobfiles/" + hostname + "-killinput")): fin = open(inputfile, "r") filedata = fin.readlines() diff --git a/InteractiveROSETTA/server/rosetta_submit.py b/InteractiveROSETTA/server/rosetta_submit.py index a7acfb5..6b2f2b2 100755 --- a/InteractiveROSETTA/server/rosetta_submit.py +++ b/InteractiveROSETTA/server/rosetta_submit.py @@ -34,6 +34,8 @@ rosetta_db = "/usr/local/rosetta/main/database" # Location of the antibody.py script and the antibody/blast databases antibody_home = "/usr/local/rosetta/tools/antibody" +# Location of the fragment tools package +fragment_tools = "/usr/local/rosetta/tools/fragment_tools" # ==================================================================================================================== def AA3to1(resn): @@ -44,7 +46,7 @@ def AA3to1(resn): indx = indx3 / 4 return "ACDEFGHIKLMNPQRSTVWYO"[indx] -def twoStageDock(nproc, inputstruct, hostfile, receptorchains, ligandchains, decoys, nfinal, randomize1, randomize2, ensemble1, ensemble2): +def doDock(nproc, inputstruct, hostfile, receptorchains, ligandchains, decoys, nfinal, randomize1, randomize2, ensemble1, ensemble2): outputdir = "." # If either ensemble1 or ensemble2 is present, then we need a file for both ensembles # If either is False, then that ensemble needs a file with only the single template from the input @@ -229,7 +231,7 @@ def twoStageDock(nproc, inputstruct, hostfile, receptorchains, ligandchains, dec print "ERROR: The ensemble scorer crashed!" print "Output: " + output exit() - # Do round 1 in MPI mode + # Do docking if (separateMPI_master): commandline = "ssh " + MPI_master + " \"cd " + iRosetta_home + "/results/" + jobID.strip() + "; (" + mpiexec + " -hostfile " + hostfile + " -np " + str(nproc) + " " + rosetta_bin + "/docking_protocol.mpi.linuxgccrelease @flags > dock.out) >& dock.err\"" else: @@ -251,128 +253,10 @@ def twoStageDock(nproc, inputstruct, hostfile, receptorchains, ligandchains, dec for output in outputfiles: os.rename(output, outputdir + "/" + output) outputfiles = glob.glob(outputdir + "/" + pdbprefix + "_*.pdb") - # If there were no constraints, we're done - if (constraintsfile): - # Now let's find the top 100 PDBs by constraint-only score, using total_score to break ties (if no constraints are - # given, then the ranking is basically just the total_score) - totalS = [] - constraintS = [] - for outputfile in outputfiles: - fin = open(outputfile, "r") - cscore = 0.0 - score = 9999999999.0 - for aline in fin: - if (aline.startswith("pose")): - score = float(aline.split()[len(aline.split())-1]) - elif (aline.startswith("atom_pair_constraint")): - cscore = float(aline.split()[len(aline.split())-1]) - fin.close() - totalS.append(score) - constraintS.append(cscore) - # Now sort - for i in range(0, len(totalS)-1): - bestindx = i - for j in range(i, len(totalS)): - if (constraintS[j] < constraintS[bestindx]): - bestindx = j - elif (constraintS[j] == constraintS[bestindx] and totalS[j] < totalS[bestindx]): - bestindx = j - temp = outputfiles[i] - outputfiles[i] = outputfiles[bestindx] - outputfiles[bestindx] = temp - temp = totalS[i] - totalS[i] = totalS[bestindx] - totalS[bestindx] = temp - temp = constraintS[i] - constraintS[i] = constraintS[bestindx] - constraintS[bestindx] = temp - winners = outputfiles[0:int(len(outputfiles) / 10)] - # Generate a list of commands for doing all the round 2 docking simulations - # Try to find the default, single processor Rosetta binary - platform = "default.linuxgccrelease" - binaries = glob.glob(rosetta_bin + "/docking_protocol.default.*") - if (len(binaries) > 0): - platform = binaries[0].split("docking_protocol")[1] - platform = platform[1:] # Get rid of the leading . - else: - binaries = glob.glob(rosetta_bin + "/docking_protocol.static.*") - if (len(binaries) > 0): - platform = binaries[0].split("docking_protocol")[1] - platform = platform[1:] # Get rid of the leading - commandlines = [] - fout = open("commandslist", "w") - for i in range(0, len(winners)): - # Generate the flags file - commandline = rosetta_bin + "/docking_protocol." + platform + " " - commandline = commandline + "-in:path:database " + rosetta_db + " " - commandline = commandline + "-in:file:s " + winners[i].strip() + " " - commandline = commandline + "-out:nstruct 10 " - commandline = commandline + "-no_filters " - if (ensemble1 or ensemble2): - commandline = commandline + "-ensemble1 ensemble1 -ensemble2 ensemble2 " - commandline = commandline + "-score:weights talaris2013_cst " - commandline = commandline + "-ignore_unrecognized_res " - commandline = commandline + "-partners " + receptorchains + "_" + ligandchains + " " - commandline = commandline + "-dock_pert 3 8 " - commandline = commandline + "-constraints:cst_file " + constraintsfile + " " # Use the tight constraints now - commandline = commandline + "-out:file:fullatom " - commandline = commandline + "-overwrite" - fout.write(commandline + "\n") - fout.close() - # Spawn the child processes - # For some reason, you cannot have mpi4py active in this script to spawn Rosetta processes - # I think it has something to do with the fact that Rosetta is MPI-aware, so having this script running with - # mpi4py activates MPI in the environment Rosetta starts in, so MPI-things get activated in Rosetta when they should - # not be activated (since you are intending to only submit a lot of individual single-CPU Rosetta sessions) and - # bad things happen - # The method below seems to work - # - # Calculate what machines will be given to each machine, duplicating if a machine has multiple CPUs - thishost = socket.gethostname() - hosts = [] - fin = open(hostfile, "r") - for aline in fin: - if (len(aline.strip()) == 0): - continue - hostname = aline.split()[0] - ncpus = int(aline.split()[1].split("=")[1]) # hostname slots=ncpus max-slots=ncpus - for i in range(0, ncpus): - hosts.append(hostname) - fin.close() - processes = [] - if (separateMPI_master): - commandline = "ssh " + MPI_master + " \"cd " + iRosetta_home + "/results/" + jobID.strip() + "; (" + mpiexec + " -hostfile " + hostfile + " -np " + str(nproc) + " python ../../dockR2.py > dock.out) >& dock.err\"" - else: - commandline = "cd " + iRosetta_home + "/results/" + jobID.strip() + "; (" + mpiexec + " -hostfile " + hostfile + " -np " + str(nproc) + " python ../../dockR2.py > dock.out) >& dock.err" - res, output = commands.getstatusoutput(commandline) - if (res): - print "ERROR: The Rosetta MPI docker, round 2, crashed!" - print "Output: " + output - exit() - # Move the outputs if desired - outputfiles = glob.glob(pdbprefix + "_*_*.pdb") - if (outputdir != "."): - try: - os.mkdir(outputdir + "/round2") - except: - pass - pdbprefix = inputstruct.split(".pdb")[0] - for output in outputfiles: - os.rename(output, outputdir + "/round2/" + output) - outputfiles = glob.glob(outputdir + "/round2/" + pdbprefix + "_*_*.pdb") - else: - try: - os.mkdir("round2") - except: - pass - pdbprefix = inputstruct.split(".pdb")[0] - for output in outputfiles: - os.rename(output, "round2/" + output) - outputfiles = glob.glob("round2/" + pdbprefix + "_*_*.pdb") - # Now again, rank by increasing constraint-only score with total_score to break ties - # Return the top 10 as the right answers - totalS = [] - constraintS = [] + # Now again, rank by increasing constraint-only score with total_score to break ties + # Return the top 10 as the right answers + totalS = [] + constraintS = [] for outputfile in outputfiles: fin = open(outputfile, "r") cscore = 0.0 @@ -412,6 +296,366 @@ def twoStageDock(nproc, inputstruct, hostfile, receptorchains, ligandchains, dec os.rename(winner, "final_%4.4i.pdb" % i) i += 1 +def setupKIC(): + # Unpack everything we need from that inputfile and generate the flags file for KIC submission + fin = open("coarsekicinput", "r") + nstruct = 1 + loopdata = [] + for aline in fin: + if (aline[0:7] == "PDBFILE"): + pdbfile = aline.split("\t")[1].strip() + f2 = open(pdbfile, "w") + elif (aline[0:8] == "SCOREFXN"): + weightsfile = aline.split("\t")[1].strip() + elif (aline[0:6] == "PARAMS"): + paramsfile = aline.split("\t")[1].strip() + f2 = open(paramsfile, "w") + elif (aline.startswith("BEGIN PDB")): + readingData = True + elif (aline.startswith("END PDB")): + f2.close() + readingData = False + elif (aline.startswith("BEGIN PARAMS")): + readingData = True + elif (aline.startswith("END PARAMS")): + f2.close() + readingData = False + elif (aline[0:19] == "BEGIN SCOREFXN DATA"): + weightsfile = "weights" + f2 = open(weightsfile, "w") + readingData = True + elif (aline[0:17] == "END SCOREFXN DATA"): + f2.close() + readingData = False + elif (readingData): + f2.write(aline.strip() + "\n") + elif (aline[0:4] == "LOOP"): + # Save the information in a list that we will iterate through later + loopdata.append(aline.strip().split("\t")[1:]) + elif (aline[0:7] == "NSTRUCT"): + nstruct = int(aline.split("\t")[1]) + elif (aline[0:7] == "PERTURB"): + perturbType = aline.split("\t")[1].strip() + fin.close() + # Get the PDB data because we're probably going to have to modify it + pdbdata = [] + fin = open(pdbfile, "r") + last_res = "00000" + for aline in fin: + if (aline.startswith("ATOM") or aline.startswith("HETATM")): + if (aline[22:27] != last_res): + last_res = aline[22:27] + pdbdata.append("") + pdbdata[len(pdbdata)-1] += aline + fin.close() + # Read the dummy residues PDB data + rsd_factory = [] + fin = open("../../data/residues.pdb", "r") + for aline in fin: + if (aline.startswith("ATOM") or aline.startswith("HETATM")): + if (aline[22:27] != last_res): + last_res = aline[22:27] + rsd_factory.append("") + rsd_factory[len(rsd_factory)-1] += aline + fin.close() + # Now construct dummy sequences for de novo loops + for i in range(0, len(loopdata)): + [loopType, sequence, begin, pivot, end] = loopdata[i] + loopBegin = int(begin) + pivot = int(pivot) + loopEnd = int(end) + if (loopType == "DE NOVO"): + # Since this is a new sequence being added, we first have to delete all the residues + # between the beginning and ending points + oldlen = 0 + for ires in range(loopEnd-1, loopBegin, -1): + pdbdata.pop(ires-1) # Rosetta indices are from 1, not 0 + #pose.delete_polymer_residue(ires) + oldlen += 1 + # Now we have to add the sequence using our nifty little "rsd_factory" pose + # The residues will have coordinates in weird places but it doesn't matter because + # KIC fixes that and puts them in the right place; they don't need to start out anywhere + # near being right + offset = 0 + for AA in sequence.strip(): + indx = "ACDEFGHIKLMNPQRSTVWY".find(AA) + 1 + pdbdata.insert(loopBegin+offset, rsd_factory[indx]) + #pose.append_polymer_residue_after_seqpos(Residue(rsd_factory.residue(indx)), loopBegin+offset, True) + offset = offset + 1 + # Now we have to update the begin and end points of the other loops if necessary + for j in range(0, len(loopdata)): + if (loopBegin < int(loopdata[j][2])): + loopdata[j][2] = int(loopdata[j][2]) + len(sequence) - oldlen + if (loopBegin < int(loopdata[j][3])): + loopdata[j][3] = int(loopdata[j][3]) + len(sequence) - oldlen + if (loopBegin < int(loopdata[j][4])): + loopdata[j][4] = int(loopdata[j][4]) + len(sequence) - oldlen + # Now maybe the sequence is longer than what was originally the length of the sequence + # between start and end, so we need to recalculate the loop end + loopEnd = loopBegin + len(sequence.strip()) + 1 + if (loopType == "DE NOVO"): + # This has to be hard-coded, because the loop is not actually there until coarse modeling happens so there's no pivot point + # other than the loop anchor residues + loopdata[i][3] = loopEnd + # Rewrite the PDB data + fout = open(pdbfile, "w") + for i in range(0, len(pdbdata)): + data = pdbdata[i] + # Renumber the residues + for aline in data.split("\n"): + if (len(aline.strip()) > 0): + fout.write(aline[0:22] + "%4i" % (i+1) + aline[26:] + "\n") + fout.close() + # Write the loops file + fout = open("in.loop", "w") + for [loopType, sequence, begin, pivot, end] in loopdata: + if (loopType == "REFINE"): + fout.write("LOOP " + str(begin) + " " + str(end) + " " + str(pivot) + " 0 0\n") + else: + fout.write("LOOP " + str(begin) + " " + str(end) + " " + str(pivot) + " 0 1\n") + fout.close() + # Write the flags file + fout = open("flags", "w") + fout.write("-in:file:s " + pdbfile + "\n") + fout.write("-database " + rosetta_db + "\n") + fout.write("-loops:loop_file in.loop\n") + fout.write("-loops:remodel perturb_kic\n") + fout.write("-loops:refine refine_kic\n") + fout.write("-ignore_unrecognized_res\n") + fout.write("-overwrite\n") + fout.write("-score:weights weights\n") + fout.write("-out:nstruct " + str(nstruct) + "\n") + fout.close() + # Return the output stem so the ensemble packer can find the PDB outputs + return pdbfile.split(".pdb")[0] + "_" + +def doFlexPep(): + # Generate the input files + fin = open("flexpepinput", "r") + readingData = False + have_cst = False + for aline in fin: + if (aline[0:7] == "PDBFILE"): + pdbfile = aline.split("\t")[1].strip() + f2 = open(pdbfile, "w") + elif (aline[0:8] == "SCOREFXN"): + weightsfile = aline.split("\t")[1].strip() + elif (aline.startswith("BEGIN PDB")): + readingData = True + elif (aline.startswith("END PDB")): + f2.close() + readingData = False + elif (aline[0:19] == "BEGIN SCOREFXN DATA"): + weightsfile = "weights" + f2 = open(weightsfile, "w") + readingData = True + elif (aline[0:17] == "END SCOREFXN DATA"): + f2.close() + readingData = False + elif (aline[0:14] == "BEGIN CST DATA"): + f2 = open("constraints.cst", "w") + readingData = True + have_cst = True + elif (aline[0:12] == "END CST DATA"): + f2.close() + readingData = False + elif (readingData): + f2.write(aline.strip() + "\n") + elif (aline.startswith("RECEPTOR")): + receptorChains = aline.split("\t")[1].strip() + elif (aline.startswith("PEPTIDE")): + peptideChain = aline.split("\t")[1].strip() + elif (aline.startswith("DECOYS")): + ndecoys = int(aline.split("\t")[1].strip()) + elif (aline.startswith("RETURNMODELS")): + nreturn = int(aline.split("\t")[1].strip()) + elif (aline.startswith("FLEXMODE")): + mode = aline.split("\t")[1].strip() + fin.close() + if (mode == "ABINITIO"): + # Generate the FASTA file for the peptide + # This is needed so we can generate fragments + fin = open(pdbfile, "r") + fout = open("peptide.fasta", "w") + fout.write("> Peptide Sequence\n") + lastres = "0000" + for aline in fin: + if (aline.startswith("ATOM") and aline[21] == peptideChain and lastres != aline[22:26]): + lastres = aline[22:26] + fout.write(AA3to1(aline[17:20])) + fout.write("\n") + fin.close() + fout.close() + # Now we have to run PSIBLAST to get a position specific matrix to generate the sequence + # profile for fragment selections + commandline = "blastpgp -i peptide.fasta -j 2 -d nr.15 -C checkpoint.pssm" + print commandline + res, output = commands.getstatusoutput(commandline) + if (res): + print "ERROR: blastpgp failed!" + exit() + # Now we have to use Rosetta's script to convert the binary checkpoint.pssm to a text + # file that can be used for sequence profiles + commandline = "perl ../../gen-sequence-profile.pl peptide.fasta checkpoint.pssm frags.chk" + print commandline + res, output = commands.getstatusoutput(commandline) + if (res): + print "ERROR: gen-sequence-profile.pl failed!" + exit() + # Now run psipred to get the secondary structure prediction + commandline = "runpsipred_single peptide.fasta" + print commandline + res, output = commands.getstatusoutput(commandline) + if (res): + print "ERROR: PSIPRED failed!" + exit() + # Now generate a simple weighting scheme for fragment selection + fout = open("simple.wghts", "w") + fout.write("# score name priority wght max_allowed extras\n") + fout.write("SecondarySimilarity 350 1.0 - psipred\n") + fout.write("RamaScore 150 2.0 - psipred\n") + fout.write("ProfileScoreL1 200 2.0 -\n") + fout.write("SequenceIdentity 100 1.0 -") # No newline here otherwise you get a duplicate!!! + fout.close() + # Setup and run fragment generation + fout = open("flags", "w") + fout.write("-database " + rosetta_db + "\n") + fout.write("-in::file::vall " + fragment_tools + "/vall.apr24.2008.extended.gz\n") + fout.write("-in::file::fasta peptide.fasta\n") + fout.write("-in::file::checkpoint frags.chk\n") + fout.write("-frags::ss_pred peptide.ss2 psipred\n") + fout.write("-frags::scoring::config simple.wghts\n") + fout.write("-frags::bounded_protocol\n") + fout.write("-frags::frag_sizes 3 5 9\n") + fout.write("-frags::n_candidates 200\n") + fout.write("-frags::n_frags 200\n") + fout.write("-out::file::frag_prefix frags\n") + fout.write("-frags::describe_fragments frags.fsc\n") + fout.close() + if (separateMPI_master): + command = "ssh " + MPI_master + " \"cd " + iRosetta_home + "/results/" + jobID.strip() + "; (" + mpiexec + " " + hostfile_arg + " hostfile_" + jobID.strip() + " " + numproc_arg + " 1 " + rosetta_bin + "/fragment_picker.mpi.linuxgccrelease @flags > frag.out) >& frag.err\"" + else: + command = "cd " + iRosetta_home + "/results/" + jobID.strip() + "; (" + mpiexec + " " + hostfile_arg + " hostfile_" + jobID.strip() + " " + numproc_arg + " 1 " + rosetta_bin + "/fragment_picker.mpi.linuxgccrelease @flags > frag.out) >& frag.err" + print command + p = Popen(args=command, stdout=PIPE, shell=True) + (out, err) = p.communicate() + # As per the flexpepdock instructions, we have to shift the fragment positions in the + # frags files by the number of residues in receptor chains + # Count the number of receptor residues + fin = open(pdbfile, "r") + nResReceptor = 0 + last_res = "0000" + for aline in fin: + if ((aline.startswith("ATOM") or aline.startswith("HETATM")) and aline[21] in receptorChains and aline[22:26] != last_res): + last_res = aline[22:26] + nResReceptor += 1 + fin.close() + fout = open("shift.csh", "w") + fout.write("set ifragfile=\"frags.200.3mers\"\n") + fout.write("set ofragfile=\"frags.200.shifted.3mers\"\n") + fout.write("set nResReceptor=" + str(nResReceptor) + "\n") + fout.write("awk '{if ( substr ( $0,1,3 ) == \"pos\" ) {print substr ( $0,0,18 ) sprintf (\"%4d\",substr ( $0,19,4 ) + '\"$nResReceptor\"' ) substr ( $0,23,1000 ) ; } else {print ; }}' $ifragfile > $ofragfile\n") + fout.write("set ifragfile=\"frags.200.5mers\"\n") + fout.write("set ofragfile=\"frags.200.shifted.5mers\"\n") + fout.write("awk '{if ( substr ( $0,1,3 ) == \"pos\" ) {print substr ( $0,0,18 ) sprintf (\"%4d\",substr ( $0,19,4 ) + '\"$nResReceptor\"' ) substr ( $0,23,1000 ) ; } else {print ; }}' $ifragfile > $ofragfile\n") + fout.write("set ifragfile=\"frags.200.9mers\"\n") + fout.write("set ofragfile=\"frags.200.shifted.9mers\"\n") + fout.write("awk '{if ( substr ( $0,1,3 ) == \"pos\" ) {print substr ( $0,0,18 ) sprintf (\"%4d\",substr ( $0,19,4 ) + '\"$nResReceptor\"' ) substr ( $0,23,1000 ) ; } else {print ; }}' $ifragfile > $ofragfile\n") + fout.close() + commandline = "tcsh shift.csh" + print commandline + res, output = commands.getstatusoutput(commandline) + if (res): + print "ERROR: Could not shift the frag files!" + exit() + # Now that we have the fragments, we can run flexpepdock + # Generate the new frags file + fout = open("flags", "w") + fout.write("-database " + rosetta_db + "\n") + fout.write("-s " + pdbfile + "\n") + fout.write("-ex1\n") + fout.write("-ex2aro\n") + fout.write("-use_input_sc\n") + if (mode == "ABINITIO"): + fout.write("-frag3 frags.200.shifted.3mers\n") + fout.write("-frag5 frags.200.shifted.5mers\n") + fout.write("-frag9 frags.200.shifted.9mers\n") + fout.write("-lowres_abinitio\n") + fout.write("-pep_refine\n") + fout.write("-nstruct " + str(ndecoys) + "\n") + if (have_cst): + fout.write("-constraints:cst_file constraints.cst\n") + if (mode == "ABINITIO"): + fout.write("-place_peptide_on_binding_site\n") + fout.write("-receptor_chain " + receptorChains + "\n") + fout.write("-peptide_chain " + peptideChain + "\n") + fout.write("-score:weights talaris2013_cst\n") + fout.close() + # Run it + if (separateMPI_master): + command = "ssh " + MPI_master + " \"cd " + iRosetta_home + "/results/" + jobID.strip() + "; (" + mpiexec + " " + hostfile_arg + " hostfile_" + jobID.strip() + " " + numproc_arg + " " + str(cpus) + " " + rosetta_bin + "/FlexPepDocking.mpi.linuxgccrelease @flags > flexpep.out) >& flexpep.err\"" + else: + command = "cd " + iRosetta_home + "/results/" + jobID.strip() + "; (" + mpiexec + " " + hostfile_arg + " hostfile_" + jobID.strip() + " " + numproc_arg + " " + str(cpus) + " " + rosetta_bin + "/FlexPepDocking.mpi.linuxgccrelease @flags > flexpep.out) >& flexpep.err" + print command + p = Popen(args=command, stdout=PIPE, shell=True) + (out, err) = p.communicate() + # Okay, now let's take the top N models as ranked by the constraints score first and + # reweighted FlexPepDock score second + # We can get this information out of the score file + pdbstem = pdbfile.split(".pdb")[0] + pdblist = [] + cst_scores = [] + rw_scores = [] + for i in range(0, ndecoys): + pdblist.append(pdbstem + "_%4.4i.pdb" % (i+1)) + cst_scores.append(0.0) + rw_scores.append(0.0) + fin = open("score.sc", "r") + for aline in fin: + if ("total_score" in aline): + fields = aline.split() + try: + rw_indx = fields.index("reweighted_sc") + except: + rw_indx = fields.index("total_score") + try: + cst_indx = fields.index("atom_pair_constraint") + except: + cst_indx = -1 + desc_indx = fields.index("description") + elif (aline.startswith("SCORE:")): + try: + pdb = aline.split()[desc_indx] + ".pdb" + score = float(aline.split()[rw_indx]) + rw_scores[pdblist.index(pdb)] = score + if (cst_indx >= 0): + score = float(aline.split()[cst_indx]) + cst_scores[pdblist.index(pdb)] = score + except: + pass + fin.close() + # Now do the select sorting + for i in range(0, len(pdblist)-1): + best = i + for j in range(i+1, len(pdblist)): + if (cst_scores[j] < cst_scores[best]): + best = j + elif (cst_scores[j] == cst_scores[best] and rw_scores[j] < rw_scores[best]): + best = j + temp = pdblist[best] + pdblist[best] = pdblist[i] + pdblist[i] = temp + temp = rw_scores[best] + rw_scores[best] = rw_scores[i] + rw_scores[i] = temp + temp = cst_scores[best] + cst_scores[best] = cst_scores[i] + cst_scores[i] = temp + # Copy them to new filename + for i in range(0, nreturn): + outfile = "final_flexpep_%4.4i.pdb" % (i+1) + os.system("cp " + pdblist[i] + " " + outfile) + # This script is used by InteractiveROSETTA to submit uploaded jobs to the C++ Rosetta, and then packages them up into # files that the client GUI can access remotely # Please note that this script is called by daemon_server.py @@ -460,7 +704,7 @@ def twoStageDock(nproc, inputstruct, hostfile, receptorchains, ligandchains, dec else: addparams = False if (addparams): - paramsfiles = glob.glob("*.params") + paramsfiles = glob.glob("*.fa.params") if (len(paramsfiles) > 0): f = open("flags", "a") f.write("-extra_res_fa") @@ -469,11 +713,20 @@ def twoStageDock(nproc, inputstruct, hostfile, receptorchains, ligandchains, dec f.write("\n") f.close() # Enter the queue -while (os.path.isfile(iRosetta_home + "/writing_to_queue")): - time.sleep(10) -f = open(iRosetta_home + "/writing_to_queue", "w") -f.write("TAKEN") -f.close() +while (True): + while (os.path.isfile(iRosetta_home + "/writing_to_queue")): + time.sleep(10) + f = open(iRosetta_home + "/writing_to_queue", "w") + f.write(this_host) + f.close() + # Wait a while, in case other nodes got in as well, then check the hostname in the file + # and wait some more if it is not this hostname + time.sleep(3) + fin = open(iRosetta_home + "/writing_to_queue", "r") + filehostname = fin.readlines()[0].strip() + fin.close() + if (filehostname == this_host): + break f = open(iRosetta_home + "/rosetta_queue", "a") f.write(jobID.strip() + "\n") f.close() @@ -485,11 +738,20 @@ def twoStageDock(nproc, inputstruct, hostfile, receptorchains, ligandchains, dec # We'll use a common file to queue jobIDs so they all run in order # First grab a mutex in case multiple instances of this script are running, so they don't query the backends at the same # time and grab the same nodes - while (os.path.isfile(iRosetta_home + "/writing_to_queue")): - time.sleep(10) - f = open(iRosetta_home + "/writing_to_queue", "w") - f.write("TAKEN") - f.close() + while (True): + while (os.path.isfile(iRosetta_home + "/writing_to_queue")): + time.sleep(10) + f = open(iRosetta_home + "/writing_to_queue", "w") + f.write(this_host) + f.close() + # Wait a while, in case other nodes got in as well, then check the hostname in the file + # and wait some more if it is not this hostname + time.sleep(3) + fin = open(iRosetta_home + "/writing_to_queue", "r") + filehostname = fin.readlines()[0].strip() + fin.close() + if (filehostname == this_host): + break f = open(iRosetta_home + "/rosetta_queue", "r") data = f.readlines() if (len(data) > 0 and data[0].strip() == jobID.strip()): @@ -508,11 +770,20 @@ def twoStageDock(nproc, inputstruct, hostfile, receptorchains, ligandchains, dec time.sleep(10) # Loop for finding free nodes while (True): - while (os.path.isfile(iRosetta_home + "/backend_query")): - time.sleep(10) - f = open(iRosetta_home + "/backend_query", "w") - f.write("TAKEN") - f.close() + while (True): + while (os.path.isfile(iRosetta_home + "/backend_query")): + time.sleep(10) + f = open(iRosetta_home + "/backend_query", "w") + f.write(this_host) + f.close() + # Wait a while, in case other nodes got in as well, then check the hostname in the file + # and wait some more if it is not this hostname + time.sleep(3) + fin = open(iRosetta_home + "/backend_query", "r") + filehostname = fin.readlines()[0].strip() + fin.close() + if (filehostname == this_host): + break # How many models do we need for certain protocols? if (protocol == "antibody"): fin = open("antibodyinput", "r") @@ -521,6 +792,13 @@ def twoStageDock(nproc, inputstruct, hostfile, receptorchains, ligandchains, dec nmodels = int(aline.split("\t")[1]) break fin.close() + elif (protocol == "kic"): + fin = open("coarsekicinput", "r") + for aline in fin: + if (aline.startswith("NSTRUCT")): + nmodels = int(aline.split("\t")[1]) + 1 + break + fin.close() elif (protocol == "backrub"): fin = open("backrubinput", "r") for aline in fin: @@ -535,11 +813,21 @@ def twoStageDock(nproc, inputstruct, hostfile, receptorchains, ligandchains, dec nmodels = int(aline.split("\t")[1]) break fin.close() + elif (protocol == "flexpep"): + fin = open("flexpepinput", "r") + for aline in fin: + if (aline.startswith("RETURNMODELS")): + nmodels = int(aline.split("\t")[1]) + break + fin.close() elif (protocol == "pmutscan"): # Take as many as we can get nmodels = 99999 # Query the backend nodes to find which nodes are free and submit to those nodes for host in hosts: + # Wait a minute in case a new job is starting, we need to wait to let the CPUs + # get busy enough that uptime reports accurate loads + #time.sleep(60) hostname = host[0] slots = host[1] if (hostname == this_host): @@ -567,7 +855,7 @@ def twoStageDock(nproc, inputstruct, hostfile, receptorchains, ligandchains, dec if (float(load_1min) < 0.5 * float(nproc)): cpus_allocated = cpus_allocated + slots selected_hosts.append([hostname, slots]) - if (protocol in ["antibody", "dock", "pmutscan", "backrub"]): + if (protocol in ["antibody", "dock", "pmutscan", "backrub", "kic", "flexpep"]): if (cpus_allocated >= nmodels): cpus = nmodels runnable = True @@ -581,11 +869,17 @@ def twoStageDock(nproc, inputstruct, hostfile, receptorchains, ligandchains, dec else: runnable = False os.remove(iRosetta_home + "/backend_query") - if (protocol in ["antibody", "dock", "pmutscan", "backrub"]): + if (protocol in ["antibody", "dock", "pmutscan", "backrub", "kic"]): # Ideally we want one processor per model, but if we have at least mincpus then let's go for it if (not(runnable) and cpus_allocated >= mincpus): cpus = cpus_allocated runnable = True + elif (protocol == "flexpep"): + # This one really needs a lot to finish in time, this is calculated such that it should + # get enough nodes to finish in one day at the most + if (not(runnable) and cpus_allocated >= nmodels / 300): + cpus = cpus_allocated + runnable = True if (runnable): break time.sleep(10) @@ -727,7 +1021,7 @@ def twoStageDock(nproc, inputstruct, hostfile, receptorchains, ligandchains, dec ensemble2 = True else: ensemble2 = False - twoStageDock(cpus, pdbfile, "hostfile_" + jobID.strip(), jumpconfig.split("_")[0], jumpconfig.split("_")[1], ncoarse, nrefined, randomize1, randomize2, ensemble1, ensemble2) + doDock(cpus, pdbfile, "hostfile_" + jobID.strip(), jumpconfig.split("_")[0], jumpconfig.split("_")[1], ncoarse, nrefined, randomize1, randomize2, ensemble1, ensemble2) elif (protocol == "pmutscan"): # Get the pdbfile, resfile, and scorefxn from the input file fin = open("scaninput", "r") @@ -776,12 +1070,20 @@ def twoStageDock(nproc, inputstruct, hostfile, receptorchains, ligandchains, dec command = "ssh " + MPI_master + " \"cd " + iRosetta_home + "/results/" + jobID.strip() + "; (" + mpiexec + " " + hostfile_arg + " hostfile_" + jobID.strip() + " " + numproc_arg + " " + str(cpus) + " " + rosetta_bin + "/pmut_scan_parallel.mpi.linuxgccrelease @flags > pmut.out) >& pmut.err\"" else: command = "cd " + iRosetta_home + "/results/" + jobID.strip() + "; (" + mpiexec + " " + hostfile_arg + " hostfile_" + jobID.strip() + " " + numproc_arg + " " + str(cpus) + " " + rosetta_bin + "/pmut_scan_parallel.mpi.linuxgccrelease @flags > pmut.out) >& pmut.err" + elif (protocol == "kic"): + outputstem = setupKIC() + if (separateMPI_master): + command = "ssh " + MPI_master + " \"cd " + iRosetta_home + "/results/" + jobID.strip() + "; (" + mpiexec + " " + hostfile_arg + " hostfile_" + jobID.strip() + " " + numproc_arg + " " + str(cpus) + " " + rosetta_bin + "/loopmodel.mpi.linuxgccrelease @flags > kic.out) >& kic.err\"" + else: + command = "cd " + iRosetta_home + "/results/" + jobID.strip() + "; (" + mpiexec + " " + hostfile_arg + " hostfile_" + jobID.strip() + " " + numproc_arg + " " + str(cpus) + " " + rosetta_bin + "/loopmodel.mpi.linuxgccrelease @flags > kic.out) >& kic.err" elif (protocol == "msd"): if (separateMPI_master): command = "ssh " + MPI_master + " \"cd " + iRosetta_home + "/results/" + jobID.strip() + "; (" + mpiexec + " " + hostfile_arg + " hostfile_" + jobID.strip() + " " + numproc_arg + " " + str(cpus) + " " + rosetta_bin + "/mpi_msd.mpi.linuxgccrelease @flags > msd.out) >& msd.err\"" else: command = "cd " + iRosetta_home + "/results/" + jobID.strip() + "; (" + mpiexec + " " + hostfile_arg + " hostfile_" + jobID.strip() + " " + numproc_arg + " " + str(cpus) + " " + rosetta_bin + "/mpi_msd.mpi.linuxgccrelease @flags > msd.out) >& msd.err" - if (protocol != "dock"): + elif (protocol == "flexpep"): + doFlexPep() + if (protocol not in ["dock", "flexpep"]): print command p = Popen(args=command, stdout=PIPE, shell=True) (out, err) = p.communicate() @@ -861,6 +1163,30 @@ def twoStageDock(nproc, inputstruct, hostfile, receptorchains, ligandchains, dec f.write(errmsg) f.close() exit() +elif (protocol == "flexpep"): + # Did we crash? The answer is yes then we did not get the required number of output models + crashed = False + errmsg = "" + try: + f = open("flexpep.err", "r") + for aline in f: + errmsg = errmsg + aline.strip() + "\n" + f.close() + except: + f = open("frag.err", "r") + for aline in f: + errmsg = errmsg + aline.strip() + "\n" + f.close() + # Sometimes warnings get outputted to the error file, so we can't know if an error really happening + # simply by checking to see if dock.err has content in it + outputfiles = glob.glob("final_flexpep_????.pdb") + if (len(outputfiles) == 0): + crashed = True + if (crashed): + f = open("errreport", "w") + f.write(errmsg) + f.close() + exit() elif (protocol == "backrub"): # Did we crash? The answer is yes then we did not get the required number of output models crashed = False @@ -879,6 +1205,24 @@ def twoStageDock(nproc, inputstruct, hostfile, receptorchains, ligandchains, dec f.write(errmsg) f.close() exit() +elif (protocol == "kic"): + # Did we crash? The answer is yes then we did not get the required number of output models + crashed = False + errmsg = "" + f = open("kic.err", "r") + for aline in f: + errmsg = errmsg + aline.strip() + "\n" + f.close() + # Sometimes warnings get outputted to the error file, so we can't know if an error really happening + # simply by checking to see if dock.err has content in it + outputfiles = glob.glob(outputstem + "*.pdb") + if (len(outputfiles) == 0): + crashed = True + if (crashed): + f = open("errreport", "w") + f.write(errmsg) + f.close() + exit() elif (protocol == "pmutscan"): # Did we crash? The answer is yes if we have an error message in pmut.err crashed = False