diff --git a/Base.py b/Base.py index 418b63f..8ffece6 100644 --- a/Base.py +++ b/Base.py @@ -28,6 +28,7 @@ import tkinter.font as tkFont from subprocess import Popen, PIPE +from pymol import cmd import ctypes import os @@ -46,7 +47,7 @@ class Base(object): TKINTER_UPDATE_INTERVAL = 100 WEBSITE = 'http://biophys.umontreal.ca/nrg' - VERSION = '2.48l' + VERSION = '2.48m' ''' ================================================================================== FUNCTION __init__ : Initialization of the variables of the interface @@ -56,6 +57,7 @@ def __init__(self, root, top, menuindex, Project_Dir, Install_Dir, NRGsuite_Dir, self.Name = Name self.OSid = OSid self.PyMOL = PyMOL + self.pymol_major_version = int(cmd.get_version()[0][0]) self.NRGsuite_Dir = NRGsuite_Dir self.Install_Dir = Install_Dir @@ -85,8 +87,8 @@ def __init__(self, root, top, menuindex, Project_Dir, Install_Dir, NRGsuite_Dir, self.menuindex = menuindex if self.menuindex != -1: - self.top.menuBar.component('NRGsuite-menu').entryconfig(self.menuindex, state='disabled') - + self.Disable_MenuItem() + self.WINDOWWIDTH = WINDOWWIDTH self.WINDOWHEIGHT = WINDOWHEIGHT @@ -137,6 +139,36 @@ def __init__(self, root, top, menuindex, Project_Dir, Install_Dir, NRGsuite_Dir, self.Clean() + ''' ================================================================================== + FUNCTION Toggle_MenuItem: Toggle the state of the menu item associated to the GUI + ================================================================================== ''' + def Toggle_MenuItem(self, state): + + if self.pymol_major_version == 2: + k = 0 + for mi in self.top.menuBar._menudict['NRGsuite'].actions(): + if k == self.menuindex: + mi.setEnabled(state) + break + k += 1 + else: + str_state = 'disabled' if state == False else 'normal' + self.top.menuBar.component('NRGsuite-menu').entryconfig(self.menuindex, state=str_state) + + ''' ================================================================================== + FUNCTION Disable_MenuItem: Disable the menu item associated to the GUI + ================================================================================== ''' + def Disable_MenuItem(self): + + self.Toggle_MenuItem(False) + + ''' ================================================================================== + FUNCTION Enable_MenuItem: Enable the menu item associated to the GUI + ================================================================================== ''' + def Enable_MenuItem(self): + + self.Toggle_MenuItem(True) + ''' ================================================================================== FUNCTION Frame_Main: Generate the Main interface containing ALL the Frames ================================================================================== ''' @@ -315,8 +347,8 @@ def Quit(self): self.root = None if self.menuindex != -1: - self.top.menuBar.component('NRGsuite-menu').entryconfig(self.menuindex, state='normal') - + self.Enable_MenuItem() + print(' Closed ' + self.Name) ''' ================================================================================== diff --git a/CleftObj.py b/CleftObj.py index b9487f3..af53d33 100755 --- a/CleftObj.py +++ b/CleftObj.py @@ -32,7 +32,7 @@ def __init__(self): def Set_CleftMD5(self): md5 = hashlib.md5() - md5.update(self.CleftFile) + md5.update(self.CleftFile.encode('utf-8')) self.CleftMD5 = md5.digest() diff --git a/Color.py b/Color.py index 540e6ea..02680d9 100755 --- a/Color.py +++ b/Color.py @@ -169,4 +169,4 @@ def CreateNoList(pTotColor, pTotalColorList): noList.sort() - return noList + return [ int(i) for i in noList ] diff --git a/FlexAID/Config1.py b/FlexAID/Config1.py index bbf9b43..2cb910d 100755 --- a/FlexAID/Config1.py +++ b/FlexAID/Config1.py @@ -915,7 +915,7 @@ def Btn_Import_Clefts(self): # LoadFiles can be string instead of list on Windows. here's a workaround if self.top.OSid == 'WIN' : - LoadFiles = self.top.root.master.splitlist(LoadFiles) # allows the normalisation of filelists, namely list of lenght 1 under Windows won't be processed as a string anymore + LoadFiles = self.top.root.master.splitlist(LoadFiles) # allows the normalisation of filelists, namely list of lenght 1 under Windows won't be processed as a string anymore if len(LoadFiles) > 0: @@ -930,7 +930,7 @@ def Btn_Import_Clefts(self): Cleft = pickle.load(in_) in_.close() self.Vars.BindingSite.Add_Cleft(Cleft) - + except IOError as IOerr: IOerrMessage = "Could not read the cleft file. Error while loading cleft file : " + LoadFile self.DisplayMessage(IOerrMessage,2) @@ -1010,7 +1010,7 @@ def Generate_CleftBindingSite(self): #self.listSpheres = [] - out = file(self.CleftTmpPath, 'w') + out = open(self.CleftTmpPath, 'w') # print self.Vars.BindingSite.listClefts for Cleft in self.Vars.BindingSite.listClefts: in_ = open(Cleft.CleftFile, 'r') diff --git a/FlexAID/IOFile.py b/FlexAID/IOFile.py index 8edda62..3722181 100755 --- a/FlexAID/IOFile.py +++ b/FlexAID/IOFile.py @@ -203,7 +203,7 @@ def Before_Kill_Frame(self): self.ProcessMolecule( True, self.LigandPath.get(), self.ATOM_INDEX, self.AtomTypes.get(), self.Anchor.get(), False, self.ProcessOnly, self.Gen3D.get(), False, 'ligand' ) - + if self.top.ProcessError: return False else: @@ -994,7 +994,7 @@ def store_InpFile(self): #HETTYP 902 1 N1 m 909 910 903 0 if Line.startswith('HETTYP'): - + ATOM = Line[6:11].strip() list = [] @@ -1010,10 +1010,10 @@ def store_InpFile(self): INDEX = Line[7:9].strip() list = [] - for i in range(0,len(Line[10:])/5): + for i in range(0,int(len(Line[10:])/5)): list.append(Line[(10+i*5):(10+5+i*5)].strip()) flexInfo[INDEX] = list - + except: self.DisplayMessage(' ERROR: Could not retrieve ligand input file', 1) return 1 diff --git a/FlexAID/ManageFiles.py b/FlexAID/ManageFiles.py index bfc2951..ac0a218 100755 --- a/FlexAID/ManageFiles.py +++ b/FlexAID/ManageFiles.py @@ -218,28 +218,32 @@ def Print_OPTIMZ(self): ================================================================================== ''' def Print_RMSDST(self): + line = '' + if self.Config2.UseReference.get(): - return 'RMSDST ' + self.IOFile.ProcessedLigandPath.get() + '\n' + line = 'RMSDST ' + self.IOFile.ProcessedLigandPath.get() + '\n' - return '' + return line ''' ================================================================================== @summary: Print_IMATRX: Prints the IMATRX line of CONFIG input ================================================================================== ''' def Print_IMATRX(self): + line = '' + if self.IOFile.AtomTypes.get() == 'Sobolev': # 8 atom types only - return 'IMATRX ' + os.path.join(self.FlexAID.FlexAIDInstall_Dir,'deps','scr_bin.dat') + '\n' + line = 'IMATRX ' + os.path.join(self.FlexAID.FlexAIDInstall_Dir,'deps','scr_bin.dat') + '\n' elif self.IOFile.AtomTypes.get() == 'Gaudreault': # 12 atom types - return 'IMATRX ' + os.path.join(self.FlexAID.FlexAIDInstall_Dir,'deps','M6_cons_3.dat') + '\n' + line = 'IMATRX ' + os.path.join(self.FlexAID.FlexAIDInstall_Dir,'deps','M6_cons_3.dat') + '\n' elif self.IOFile.AtomTypes.get() == 'Sybyl': # 26 atom types #return 'IMATRX ' + os.path.join(self.FlexAID.FlexAIDInstall_Dir,'deps','MC_10p_3.dat') + '\n' #return 'IMATRX ' + os.path.join(self.FlexAID.FlexAIDInstall_Dir,'deps','MC_5p_norm_P10_M2_2.dat') + '\n' - return 'IMATRX ' + os.path.join(self.FlexAID.FlexAIDInstall_Dir,'deps','MC_st0r5.2_6.dat') + '\n' + line = 'IMATRX ' + os.path.join(self.FlexAID.FlexAIDInstall_Dir,'deps','MC_st0r5.2_6.dat') + '\n' - return '' + return line ''' ================================================================================== @summary: Print_PERMEA: Prints the PERMEA line of CONFIG input @@ -247,7 +251,8 @@ def Print_IMATRX(self): def Print_PERMEA(self): Permea = 1.00 - float(self.Config3.Permeability.get()) - return 'PERMEA ' + str(Permea) + '\n' + line = 'PERMEA ' + str(Permea) + '\n' + return line ''' ================================================================================== @summary: Print_VAR: Prints the VAR* and SPACER lines of CONFIG input @@ -357,7 +362,7 @@ def Hash_CONFIG(self): line += ' %.3f' % self.Config1.Vars.BindingSite.Sphere.Center[2] line += ' %.3f\n' % self.Config1.Vars.BindingSite.Sphere.Radius - hasher.update(line) + hasher.update(line.encode('utf-8')) elif rngOpt == 'LOCCLF': self.Config1.Generate_CleftBindingSite() @@ -372,14 +377,14 @@ def Hash_CONFIG(self): hasher = General.hashfile_update(self.TmpFile, hasher) - hasher.update(self.Print_OPTIMZ()) - hasher.update(self.Print_RMSDST()) - hasher.update(self.Print_IMATRX()) - hasher.update(self.Print_PERMEA()) - hasher.update(self.Print_VAR()) - hasher.update(self.Print_SLV()) - hasher.update(self.Print_HET()) - hasher.update(self.Print_Scoring()) + hasher.update(self.Print_OPTIMZ().encode('utf-8')) + hasher.update(self.Print_RMSDST().encode('utf-8')) + hasher.update(self.Print_IMATRX().encode('utf-8')) + hasher.update(self.Print_PERMEA().encode('utf-8')) + hasher.update(self.Print_VAR().encode('utf-8')) + hasher.update(self.Print_SLV().encode('utf-8')) + hasher.update(self.Print_HET().encode('utf-8')) + hasher.update(self.Print_Scoring().encode('utf-8')) return hasher.digest() @@ -526,7 +531,7 @@ def Print_FLEXSC(self): Permea = 1.00 - float(self.Config3.RotPermeability.get()) lines += 'ROTPER ' + str(Permea) + '\n' - return lines + return lines.encode('utf-8') ''' ================================================================================== FUNCTION Create_ConsFile: Creates the constraints file diff --git a/FlexAID/Simulation.py b/FlexAID/Simulation.py index a086ea8..9a9bcfa 100755 --- a/FlexAID/Simulation.py +++ b/FlexAID/Simulation.py @@ -498,8 +498,7 @@ def OrderFledih(self): tot = len(self.ListAtom) # Get all the keys in the Dictionary (ALL the Atoms) - order = self.dictFlexBonds.keys() - order.sort() + order = sorted(list(self.dictFlexBonds.keys())) for k in order: diff --git a/General.py b/General.py index c00f695..2598bec 100755 --- a/General.py +++ b/General.py @@ -298,7 +298,7 @@ def hashfile_update(file, hasher): buf = afile.read(BLOCKSIZE) while len(buf) > 0: - hasher.update(buf) + hasher.update(buf.encode('utf-8')) buf = afile.read(BLOCKSIZE) afile.close() diff --git a/GetCleft/Volume.py b/GetCleft/Volume.py index ac742c9..890a0cd 100755 --- a/GetCleft/Volume.py +++ b/GetCleft/Volume.py @@ -86,6 +86,7 @@ def run(self): else: Lines = out.splitlines() for Line in Lines: + Line = Line.decode('utf-8') if Line.startswith('Volume'): Cleft.Volume = float(Line[8:].strip()) self.queue.put(lambda: self.top.Init_Table()) diff --git a/Plugin/NRGsuite.py b/Plugin/NRGsuite.py index 3e04563..b521911 100755 --- a/Plugin/NRGsuite.py +++ b/Plugin/NRGsuite.py @@ -40,6 +40,9 @@ import time +from pymol import cmd +pymol_major_version = int(cmd.get_version()[0][0]) + '''================================================================================================= FUNCTION get_default_path_for_OSid: returns the default (and preferred) installation path for any OS =================================================================================================''' @@ -123,12 +126,6 @@ def get_default_path_for_OSid(): #------------------------------------------------------------------# def __init__(self): - # workaround PyMOL's legacy plugin system - if not hasattr(self.menuBar, 'component'): - class DummyComponent: - def __init__(self, _): pass - def entryconfig(*_, **_k): pass - self.menuBar.component = DummyComponent self.ProjectName = '' self.Project_Dir = '' @@ -201,9 +198,12 @@ def entryconfig(*_, **_k): pass 'CfgFile', label=' About', command = lambda s=self, menuindex=9 : StartAbout(s, menuindex)) - + # Make the Load - Create projects button clickable only - EnableDisableMenu(self, ['normal','normal','disabled','normal','disabled','disabled','normal'] ) + if pymol_major_version == 2: + EnableDisableMenuQT(self, [True,True,False,True,False,False,True] ) + else: + EnableDisableMenu(self, ['normal','normal','disabled','normal','disabled','disabled','normal'] ) #================================================================================ # STARTING GetCleft Conditional... @@ -277,16 +277,47 @@ def StartCloseProject(self, menuitem): self.RootGetCleft = None print(' GetCleft interface successfully closed.') - EnableDisableMenu(self, ['normal','normal','disabled','disabled','disabled','disabled','normal'] ) + if pymol_major_version == 2: + EnableDisableMenuQT(self, [True,True,False,True,False,False,True] ) + else: + EnableDisableMenu(self, ['normal','normal','disabled','normal','disabled','disabled','normal'] ) print('\n The project \'' + self.ProjectName + '\' was closed.') + #================================================================================ + # Find children item in QMenu + #================================================================================ + def findMenuItem(self, menu, name): + for mi in menu.actions(): + if mi.text().strip() == name: + return mi + return None + #================================================================================ # Set the NRGsuite Menu Options to Enable when a Project is created or loaded. # Set to disable at start up or when a project is closed. #================================================================================ - def EnableDisableMenu(self, states): + def EnableDisableMenuQT(self, states): + + menuItems = [ + 'New Project...', 'Load Project...', 'Close Project', + 'Preferences', + 'Open FlexAID...', 'Open GetCleft...', + 'About' + ] + + NRGsuite = self.menuBar._menudict['NRGsuite'] + for menuItem in menuItems: + mi = findMenuItem(self, NRGsuite, menuItem) + if mi is None: continue + mi.setEnabled(states.pop(0)) + #================================================================================ + # Set the NRGsuite Menu Options to Enable when a Project is created or loaded. + # Set to disable at start up or when a project is closed. + #================================================================================ + def EnableDisableMenu(self, states): + self.menuBar.component('NRGsuite-menu').entryconfig(0, state=states.pop(0)) # new self.menuBar.component('NRGsuite-menu').entryconfig(1, state=states.pop(0)) # load self.menuBar.component('NRGsuite-menu').entryconfig(2, state=states.pop(0)) # close diff --git a/Project/LoadProject.py b/Project/LoadProject.py index d5c81b0..d89c68d 100755 --- a/Project/LoadProject.py +++ b/Project/LoadProject.py @@ -328,7 +328,7 @@ def Btn_Cancel_Clicked(self): def Btn_Load_Clicked(self, *args): self.Update_ProjectFile() - + self.top.Project_Dir = self.ActualDirPath self.top.ProjectName = self.ActualFileName @@ -343,8 +343,11 @@ def Btn_Load_Clicked(self, *args): ================================================================================== ''' def After_Quit(self): - NRGsuite.EnableDisableMenu(self.top, [ 'disabled', 'disabled', 'normal', 'normal', 'normal', 'normal', 'normal' ] ) - + if self.pymol_major_version == 2: + NRGsuite.EnableDisableMenuQT(self.top, [ False, False, True, True, True, True, True ] ) + else: + NRGsuite.EnableDisableMenu(self.top, [ 'disabled', 'disabled', 'normal', 'normal', 'normal', 'normal', 'normal' ] ) + ''' ================================================================================== FUNCTION Btn_Browse_Clicked: Browse to specify the directory to install the project. ================================================================================== ''' diff --git a/Project/NewProject.py b/Project/NewProject.py index bab0aba..ba95af4 100755 --- a/Project/NewProject.py +++ b/Project/NewProject.py @@ -204,8 +204,11 @@ def Btn_Cancel_Clicked(self): FUNCTION After_Quit: Do some tasks after killing a frame ================================================================================== ''' def After_Quit(self): - - NRGsuite.EnableDisableMenu(self.top, [ 'disabled', 'disabled', 'normal', 'normal', 'normal', 'normal', 'normal' ] ) + + if self.pymol_major_version == 2: + NRGsuite.EnableDisableMenuQT(self.top, [ False, False, True, True, True, True, True ] ) + else: + NRGsuite.EnableDisableMenu(self.top, [ 'disabled', 'disabled', 'normal', 'normal', 'normal', 'normal', 'normal' ] ) ''' ================================================================================== FUNCTION Btn_Create_Clicked: Create the new project then quit the application.