""" python/ui/model.py: CCP4MG Molecular Graphics Program Copyright (C) 2001-2008 University of York, CCLRC Copyright (C) 2009-2011 University of York Copyright (C) 2012 STFC This library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 3, modified in accordance with the provisions of the license to address the requirements of UK law. You should have received a copy of the modified GNU Lesser General Public License along with this library. If not, copies may be downloaded from http://www.ccp4.ac.uk/ccp4license.php This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. """ from point_funcs import * from utils import * import utils import os import string import re from mgapp import * from mmdb2 import * from mmut import * from dataobj import * from model_selection import * from moleculargraphicsmodel import * from resources import * import build from MolLabel import * from EditHistory import * import pygl_coord import mmut from global_definitions import * import model_colour import time from PyQt4 import QtCore #----------------------------------------------------------------------- def openpdbfile (filename='',name='',drawing_style='bonds:all_atoms',customResCIFFiles={}, **keywords): #----------------------------------------------------------------------- import re f = openFile(filename,'r') if not f: MGGUI().WarningMessage("Error opening file " + filename) return [1,'Error opening file '+filename] l = f.read() f.close() if re.search('html',l) and (filename.lower().endswith('pdb') or filename.lower().endswith('pdb.gz')): print "found html" if not re.search('HEADER',l): return [1, 'Error reading file: '+filename + \ '\n the file appears to be an html file' ] else: rv = strip_html_from_PDB(filename=filename) if rv[0]: return [1,rv[1]] m = MolData (filename=filename,name=name) if keywords and hasattr(keywords,"has_key") and keywords.has_key("check_graphs"): m.check_graphs = int(keywords["check_graphs"]) print "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Setting check_graphs to",m.check_graphs m.setCustomResCIFFiles(customResCIFFiles) rv = m.loaddata(warnings=1) print "rv",rv if rv[0]==1 or rv[0]==MolData.NO_ATOMS_IN_CIF_FILE: m.delete() if rv[0]!=MolData.NO_ATOMS_IN_CIF_FILE: MGGUI().WarningMessage("Error opening file " + filename + '\n'+rv[1]) return [rv[0],'Error loading file: '+filename+'\n'+rv[1]] return [0,m] #------------------------------------------------------------------ #------------------------------------------------------------------ #------------------------------------------------------------------ # The Model class #------------------------------------------------------------------ #------------------------------------------------------------------ #------------------------------------------------------------------ class MolData(DataObj,ModelAnalysis,EditHistory): NO_ATOMS_IN_CIF_FILE = -9999 class_dependents = {} last_MolData_number = 0 # save the 'last' molecule/model/chain colour colour_counter = {} colour_counter['bymol']='' restype_menu = ['amino acid','nucleic acid','saccharide','water','solute','monomer','metal','nucleotide'] restype_alias = ['amino_acid','nucleic_acid','saccharide','water','solute','monomer','metal','nucleotide'] restype_code = [RESTYPE_PEPTIDE,RESTYPE_NUCL,RESTYPE_SACH,RESTYPE_SOLVENT,RESTYPE_SOLUTE,RESTYPE_NONPOLY,RESTYPE_METAL,RESTYPE_NUCL] secstr_code = ['N','S','B','3','4','5','H'] secstr_code_dssp = ['N','E','B','T 3','T 4','T 5','H'] secstr_enum_dssp = [SSE_None, SSE_Strand, SSE_Strand, SSE_3Turn,SSE_4Turn,SSE_5Turn,SSE_Helix ] secstr_menu = ['No structure','Beta strand','Beta bulge','3-turn', '4-turn','5-turn','Alpha helix'] secstr_alias = ['none', 'strand', 'bulge', '3turn', '4turn', '5turn', 'helix'] secstr_enum = [SSE_None, SSE_Strand, SSE_Bulge, SSE_3Turn,SSE_4Turn,SSE_5Turn,SSE_Helix ] #------------------------------------------------------------------ def __init__(self,filename=[],name='',dataparams={},restore_from_version=0,**kw): #------------------------------------------------------------------ #print "model.MolData.__init__",name,filename,dataparams # Initialise data that will be over-written by restore self.customResCIFFiles = {} self.show_aromatic_rings = 1 if hasattr(dataparams,"has_key") and dataparams.has_key("name"): name = dataparams["name"] DataObj.__init__(self,'MolData',name=name,module='model', \ filename=filename,dataparams=dataparams) ModelAnalysis.__init__(self) EditHistory.__init__(self) self.molHnd = '' self.spline_selHnd = 0 self.worm_selHnd = 0 self.check_graphs = True self.splineinfo_ribbon = SplineInfo() self.splineinfo_worm = SplineInfo() # Selection handle to all atoms selected, visible and drawn # in a 'bonding' style self.do_update_all_bonded_atoms = 0 # Flag change in data object that requires total redraw self.changedSplines = [] # Change in visibiilty/selection of spline object self.changedConnected = [] # Change in visibiilty/selection of connected object (bonds/cylinders etc) self.all_bonded_atoms = 0 self.all_bonded_atoms_spline = 0 MolData.last_MolData_number = MolData.last_MolData_number+1 import copy self.MolData_number = copy.deepcopy(MolData.last_MolData_number) self.charge_loaded = 0 # ?Charge loaded? 1=derived from atom energy type # (in MolDisp:apply_colour) self.moving = 0 self.masterCrystal = '' self.treeModel = None #print 'MolData.init dataparams',dataparams self.saved_dataparams = dataparams import model_symmetry self.model_symmetry = model_symmetry.model_symmetry(self.name) if dataparams.has_key('model_symmetry'): self.model_symmetry.setParams(dataparams['model_symmetry']) #print MolData.colour_counter['bymol'] #MolData.colour_counter['bymol'] = MGCOLOUR().next(MolData.colour_counter['bymol'],exclude=['black','white']) if not hasattr(self,"mol_colour") or not self.mol_colour: #self.mol_colour = MolData.colour_counter['bymol'] self.mol_colour = '' #print 'MolData.mol_colour',self.mol_colour self.cif_bio_matrices = [] try: if self.filename[2].endswith(".cif"): import Assemblies_BioPython self.cif_bio_matrices = Assemblies_BioPython.getAssemblyMatricesFromCIFFile(self.filename[2]) except: pass #------------------------------------------------------------------ def toggleAromaticity(self): #------------------------------------------------------------------ self.show_aromatic_rings = not self.show_aromatic_rings self.GetMolBonds() self.redraw_all_objects() import rebuild rebuild.UpdateDisplay() #------------------------------------------------------------------ def setCustomResCIFFiles(self,customResCIFFiles): #------------------------------------------------------------------ print "setCustomResCIFFiles" self.customResCIFFiles = customResCIFFiles if hasattr(self.molHnd,"setCustomResCIFFiles"): self.molHnd.setCustomResCIFFiles(mmut.map_string_string(self.customResCIFFiles)) output = self.GetMolBonds() self.redraw_all_objects() import rebuild rebuild.UpdateDisplay() #------------------------------------------------------------------ def deleteAll(self): #------------------------------------------------------------------ if self: # Are there any other objects that should be deleted # along with this one (eg Crystal gets deleted with map) dependents = self.getDependentsForDeletion() #print 'displayTable deleteDataObj dependents',dependents self.delete() if dependents: # In principle there could be a recursion here. for dep in dependents: dep_target = get_dataobj(name=dep) if dep_target: dep_target[0].delete() else: dep_target = get_dispobj(name=dep) if dep_target: dep_target.delete() #------------------------------------------------------------------ def delete(self,delete='',**keywords): #------------------------------------------------------------------ # Save user data if self.moving: self.move() MODELINFO().save(set=self.name_label,filename=self.filename) #If this MolData object does not have a clone then close #the MolInfo data set duplicate = 0 for obj in get_dataobj(object_type='MolData'): if obj != self and obj.filename == self.filename: duplicate=1 if not duplicate: MODELINFO().close(set=self.name_label) DataObj.delete(self) molHnd = getattr(self,'molHnd',None) if molHnd: molHnd.DeleteAllSelections() molHnd.FreeFileMemory() if os.environ.has_key("CCP4MG_DEBUG_MEMORY"): print "del",molHnd molHnd.thisown = 0 import _mmut _mmut.delete_CMMANManager(molHnd) del self def __del__(self): print "MolData.__del__ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" #------------------------------------------------------------------ def getDependentsForDeletion(self): #------------------------------------------------------------------ # This method return any other objects that should be deleted along with # this one. We need to delete the crystal object xtl_list = [] xtl = CRYSTALMANAGER().getCrystal(self.name) if xtl: xtl_list.append(xtl) return xtl_list #---------------------------------------------------------------------- def get_label(self): #---------------------------------------------------------------------- if PM('atom_label_params').get('show_number_label'): return str(self.MolData_number)+') '+self.name_label else: return self.name_label #---------------------------------------------------------------------- def applyDrawingStyle(self,drawing_style='',keep_display_objects=-1,chosen={},mgpic_file='',force_recolour_bymol=False): #---------------------------------------------------------------------- if not drawing_style and not mgpic_file: drawing_style = PICTUREWIZARD().default_drawing_style if drawing_style == 'all_atoms' and self.ca_only: drawing_style = 'bonds:trace_and_ligands' if keep_display_objects == 0: togo = [] for obj in self.objinsts: if not obj.master_application: togo.append(obj) #print "MolData.applyDrawingStyle togo",togo dobj = { 'MolData1' : self.name } rv = PICTUREWIZARD().create_picture(drawing_style=drawing_style,chosen_dataobj = dobj ,chosen=chosen, keep_display_objects=keep_display_objects,mgpic_file=mgpic_file,force_recolour_bymol=force_recolour_bymol) #print "applyDrawingStyle",rv if rv[0]: if not self.objinsts: # Picture wizard has failed and not current display objects so just draw one object self.add_object(object_type='MolDisp',visible=1) else: # Created new objects so delete old if keep_display_objects == 0: for obj in togo: #print "Deleting",obj obj.delete() del togo self.lastWizardRun = drawing_style return rv #---------------------------------------------------------------------- def get_attribute ( self, attb ='',parent_selection='',qualifier='',PAtom=None,chains=[],force_recolour_bymol=False): #----------------------------------------------------------------------- selindexp = pygl_coord.intp() #print "get_attribute",attb,qualifier # beware picture wizard scripts expect model_list to be ['0'] or a list of models if ['peptide_list','strand_list'].count(attb): import copy parent_selection = copy.deepcopy(qualifier) if attb == 'peptide_list': qualifier = 'peptide' elif attb == 'strand_list': qualifier = 'nucleic' attb = 'chain_list' if attb == 'model_list': mm = [] if hasattr(self,'nmr_models') and self.nmr_models: for mod in range(self.first_nmr_model,self.nmr_models+1): mm.append ('/'+str(mod)) else: mm = ['/1'] sym_models = self.model_symmetry.get_symmetry_models() # Add the symids for item in sym_models: mm.append(item+' '+self.model_symmetry.modelSymid(item[1:])) return mm if attb == 'model_number_list': mm = [] if hasattr(self,'nmr_models') and self.nmr_models: for mod in range(self.first_nmr_model,self.nmr_models+1): mm.append ('/'+str(mod)) else: mm = ['/1'] sym_models = self.model_symmetry.get_symmetry_models() # Add the symids for item in sym_models: mm.append(item) return mm elif attb == 'chain_list': mm = [] if qualifier == 'peptide': source = self.peptides elif qualifier == 'nucleic': source =self.nucleics elif qualifier == 'water': source =self.solvent_chains elif qualifier == '': source = self.chains else: pass #pModel = self.molHnd.GetModel(1) for chain in source: #mm.append(CModelPtr(self.molHnd.GetChain(1,chain))) if chain: #mm.append (chain+'/') mm.append (chain) else: mm.append("// /") return mm elif attb == 'secstr_list': mask = inta(7) for i in range(0,7): mask[i] = 0 mask[1]=1 mask[6]=1 output = self.molHnd.ListSecStructure(mask) #print "ListSecStructure output",output mm = string.split(output,'\n') if not mm[-1]: mm.pop() #print "mm",mm return mm elif attb == 'monomer_list': mm = [] if len(self.monomers) > 0: if chains and len(chains)>0 and len(chains[0])>0: chainSel = self.molHnd.NewSelection() neighbSel = self.molHnd.NewSelection() self.molHnd.Select(chainSel,STYPE_ATOM,0,chains[0].rstrip('/').strip(),ANY_RES,"*",ANY_RES,"*","*","*","*","*",SKEY_NEW ) selindexp = pygl_coord.intp() selAtoms = mmut.GetAtomSelIndex(self.molHnd,chainSel,selindexp) nSelAtoms = selindexp.value() self.molHnd.SelectNeighbours(neighbSel,STYPE_ATOM,selAtoms,nSelAtoms,0.0,4.0,SKEY_NEW) for pp in self.monomers: monSel = self.molHnd.NewSelection() self.molHnd.Select(monSel,STYPE_ATOM,pp,SKEY_NEW) self.molHnd.Select(monSel,STYPE_ATOM,neighbSel,SKEY_AND) selindexp = pygl_coord.intp() selAtoms = mmut.GetAtomSelIndex(self.molHnd,monSel,selindexp) nSelAtoms = selindexp.value() if nSelAtoms>0: print nSelAtoms,"in chain",chains[0].rstrip('/').strip(), " and monomer",pp mm.append(pp) self.molHnd.DeleteSelection(monSel) self.molHnd.DeleteSelection(chainSel) self.molHnd.DeleteSelection(neighbSel) else: for pp in self.monomers: mm.append (pp) return mm elif attb == 'res_list': import copy res_list = [] qualifer_selHnd = 0 if ["' '",' ','UNNAMED'].count(parent_selection): parent_selection = '/1//' else: parent_selection = re.sub('/0','/1',parent_selection) if qualifier == 'monomers': mm = [] for pp in self.monomers: mm.append (pp) return mm if qualifier == 'ligands': mm = [] for pp in self.monomers: mm.append (pp) return mm elif qualifier == '': sel = copy.deepcopy(parent_selection) elif qualifier == 'peptide': sel = parent_selection+'('+MODELINFO().get_names_string(key='amino_acid',set=self.name_label)+')' elif qualifier == 'nucleic': sel = parent_selection+'('+MODELINFO().get_names_string(key='nucleic_acid',set=self.name_label)+')' elif qualifier == 'water': sel = copy.deepcopy(parent_selection) else: self.parse_selection(qualifier) if not rv[0]: qualifer_selHnd = rv[1] #print "res_list qualifier,sel",qualifier,sel selHnd = self.molHnd.NewSelection() self.molHnd.Select(selHnd,STYPE_RESIDUE,sel,SKEY_NEW) if qualifer_selHnd: self.molHnd.Select(selHnd,STYPE_RESIDUE,qualifer_selHnd,SKEY_AND) self.molHnd.DeleteSelection(qualifier_selHnd) for ch in chains: chselHnd = self.molHnd.NewSelection() self.molHnd.Select(chselHnd,STYPE_RESIDUE,0,ch,ANY_RES,"*",ANY_RES,"*","*","*","*","*",SKEY_NEW ) self.molHnd.Select(selHnd,STYPE_RESIDUE,chselHnd,SKEY_AND) self.molHnd.DeleteSelection(chselHnd) selindexp = pygl_coord.intp() selResidues = newPPCResidue() #nselRes =self.molHnd.GetSelIndex(selHnd,selResidues) selResidues = mmut.GetResidueSelIndex(self.molHnd,selHnd,selindexp) nselRes = selindexp.value() if nselRes > 0: for ir in range(0,nselRes): pcres = getPCResidue(selResidues,ir) #chnid = str(pcres.GetChainID()) #if not chnid or chnid == ' ': chnid = '// ' #resname = chnid + '/' + str(pcres.GetSeqNum()) #inscode = pcres.GetInsCode() #if inscode: resname = resname + '.' + inscode #resname = resname + "(" + pcres.GetResName() + ')' #res_list.append(resname) self.molHnd.DeleteSelection(selHnd) #delPPCResidue( selResidues) return res_list elif ['atom_list','first_atom'].count(attb): atom_list = [] #print "atom_list qualifier",qualifier selHnd = self.molHnd.NewSelection() #If the selection is over all models then limit to model 1 parent_selection = re.sub('/0','/1',parent_selection) self.molHnd.Select(selHnd,STYPE_ATOM,parent_selection,SKEY_NEW) selAtoms = newPPCAtom() #nselAtom =self.molHnd.GetSelIndex(selHnd,selAtoms) selAtoms = mmut.GetAtomSelIndex(self.molHnd,selHnd,selindexp) nselAtom = selindexp.value() if attb == 'first_atom': nselAtom = min(nselAtom,1) if nselAtom > 0: pcatm = getPCAtom(selAtoms,0) chnid = str(pcatm.GetChainID()) if not chnid or chnid == ' ': chnid = '// ' resname = chnid + '/' + str(pcatm.GetSeqNum()) inscode = pcatm.GetInsCode() if inscode: resname = resname + '.' + inscode resname = resname + "(" + pcatm.GetResName() + ')' for ia in range(0,nselAtom): pcatm = getPCAtom(selAtoms,ia) name = string.strip(str( pcatm.name)) alt = pcatm.GetAltLoc() if alt: name = name + ':' + alt atom_list.append(resname+'/'+name) self.molHnd.DeleteSelection(selHnd) #print "get_attribute atom_list",atom_list return atom_list elif attb == 'selobj_list': retval,user_selection= MODELINFO().get_info( set=[self.name_label],info='user_selection') selobj_labels = user_selection.keys() i = 0 for obj in self.get_dispobj(object_type='MolDisp'): i = i+1 selobj_labels.append(str(i)+':'+obj.selection_label) selobj_list = user_selection.keys() selobj_list.extend(self.objnames) ret = [] ret.append(selobj_list) ret.append(selobj_labels) #print "ret",ret return ret elif attb == 'molecule_colour': #print force_recolour_bymol if not self.mol_colour or force_recolour_bymol: #print "Need to get a colour" MolData.colour_counter['bymol'] = MGCOLOUR().next('',exclude=['black','white']) self.mol_colour = MolData.colour_counter['bymol'] dobjs = get_dataobj(object_type='MolData') """ for dobj in dobjs: print dobj.name, self.name if force_recolour_bymol and dobj.name == self.name: break # We are hoping that force_recolour_bymol is being used on ALL objects. Otherwise this is hopeless. if dobj.name != self.name and dobj.mol_colour == self.mol_colour: print "I am",self.name,". ",dobj.name," is already using",self.mol_colour MolData.colour_counter['bymol'] = MGCOLOUR().next(dobj.mol_colour,exclude=['black','white']) self.mol_colour = MolData.colour_counter['bymol'] print "Now try",self.mol_colour """ i = 0 inUse = True while inUse and i<20: inUse = False for dobj in dobjs: if force_recolour_bymol and dobj.name == self.name: break # We are hoping that force_recolour_bymol is being used on ALL objects. Otherwise this is hopeless. if dobj.name != self.name and dobj.mol_colour == self.mol_colour: #print "I am",self.name,". ",dobj.name," is already using",self.mol_colour inUse = True MolData.colour_counter['bymol'] = MGCOLOUR().next(dobj.mol_colour,exclude=['black','white']) self.mol_colour = MolData.colour_counter['bymol'] #print "Now try",self.mol_colour i = i + 1 break #print return self.mol_colour elif attb == 'ca_only': return self.ca_only elif attb == 'element_list': status,protocols = MODELINFO().get_info( set=self.name_label,info='selection_protocols',key='element') if not status and protocols.has_key('element') and protocols['element'].has_key('ORDER'): return protocols['element']['ORDER'] else: return [] elif attb == 'energy_type': if PAtom: mask = pygl_coord.inta(20) for i in range(20): mask[i] = 0 mask[10] = 1 text_label = self.molHnd.AtomLabel(PAtom,mask) #print 'MolData.get_attribute',text_label return text_label return '' #------------------------------------------------------------------ def dataparams(self,all=1): #------------------------------------------------------------------ # save the key data which is necessary when restoring the # object on restart or 'restore status' datapar = DataObj.dataparams(self) sym_mates = self.model_symmetry.getSymmetryMates() if sym_mates: datapar['symmetry_mates']=sym_mates datapar['model_symmetry']=self.model_symmetry.getParams() if self.molHnd.GetIsTransformed(): tmat = self.molHnd.GetTransform() datapar['transform_matrix']=tmat if hasattr(self,'check_graphs'): datapar['check_graphs'] = self.check_graphs if hasattr(self,'animation') and self.animation: datapar['load_animation'] = self.animation.params() if hasattr(self,'DSSP_file'): datapar['DSSP_file'] = self.DSSP_file if hasattr(self,'mol_colour'): datapar['mol_colour'] = self.mol_colour if hasattr(self,'lastWizardRun'): datapar['lastWizardRun'] = self.lastWizardRun if hasattr(self,'show_aromatic_rings'): datapar['show_aromatic_rings'] = self.show_aromatic_rings return datapar #-------------------------------------------------------------------------- def update_data_status(self,shadowdisp): #-------------------------------------------------------------------------- import utils if isinstance(shadowdisp,MolData): other_datapars = shadowdisp.dataparams() else: other_datapars = shadowdisp.dataparams rv,diffs,undiffs = utils.dict_diffs(self.dataparams(),other_datapars) #print "MolData diffs",diffs #print "MolData undiffs",undiffs if diffs.has_key('load_animation'): import Animation if hasattr(self,'animation'): if not other_datapars.has_key('load_animation') or \ not other_datapars['load_animation']: self.animation.delete() elif self.animation.filename == other_datapars['load_animation']['filename']: self.animation.update_data_status(other_datapars['load_animation']) else: self.animation.delete() self.animation = Animation.Animation(parent=self, \ params=other_datapars['load_animation']) elif other_datapars.has_key('load_animation') and \ other_datapars['load_animation']: self.animation = Animation.Animation(parent=self, \ params=other_datapars['load_animation']) elif undiffs.has_key('load_animation'): if hasattr(self,'animation'): self.animation.delete() if diffs.has_key('symmetry_mates'): self.model_symmetry.update_data_status(other_datapars['symmetry_mates']) elif undiffs.has_key('symmetry_mates'): self.model_symmetry.update_data_status( [] ) if diffs.has_key('transform_matrix'): vtmat = [] vtran = [] ii = 0 for i in range(0,3): for j in range(0,3): vtmat.append(diffs['transform_matrix'][ii]) ii = ii + 1 vtran.append(diffs['transform_matrix'][ii]) ii = ii + 1 self.molHnd.SetTransform(vtmat,vtran,True) self.update_dependents('transform') elif undiffs.has_key('transform_matrix'): self.molHnd.UnSetTransform(True) self.update_dependents('transform') if diffs.has_key('customResCIFFiles'): self.setCustomResCIFFiles(diffs['customResCIFFiles']) rv = DataObj.update_data_status(self,shadowdisp) if diffs or undiffs: self.update_gui.append(['update']) rv = 1 return rv #----------------------------------------------------------------------- def update_matrix(self,input_matrix): #----------------------------------------------------------------------- vtmat = [] vtran = [] ii = 0 for i in range(0,3): for j in range(0,3): vtmat.append(input_matrix[ii]) ii = ii + 1 vtran.append(input_matrix[ii]) ii = ii + 1 self.molHnd.SetTransform(vtmat,vtran,True) self.update_dependents('transform') #----------------------------------------------------------------------- def update_all_bonded_atoms(self): #----------------------------------------------------------------------- ''' Update the selection handle which flags all selected atoms in all visible bonded MolDisp objects. Unset for only one visible MolDisp ''' # Note: excluding objects with master_application set (ie those # owned by an application) This gets round problems with coming # out of interactive selection with unwanted bonds drawn. But it # may not be a good long term solution if (not self.changedSplines) and (not self.changedConnected) and (not self.do_update_all_bonded_atoms) : return #print 'update_all_bonded_atoms',self.changedSplines,self.changedConnected #start_time = time.clock() changed_externally_bonded = 0 if self.changedSplines or self.do_update_all_bonded_atoms: changed_externally_bonded = 1 else: for objname in self.changedConnected: obj = self.get_dispobj(name=objname) if obj: changed_externally_bonded = obj.Connectivity.GetNumberOfExternalBonds() # Delete old selection handle for all splined atoms if hasattr(self,'worm_selHnd') and self.worm_selHnd>= 0: self.molHnd.DeleteSelection(self.worm_selHnd) self.worm_selHnd = -1 if hasattr(self,'spline_selHnd') and self.spline_selHnd>= 0: self.molHnd.DeleteSelection(self.spline_selHnd) self.spline_selHnd = -1 # How many visible bonded objects? nvis = 0 spline_objects = [] # list of visible objects in spline style worm_objects = [] # list of visible objects in worm style for obj in self.get_dispobj(object_type='MolDisp'): if obj.visible and not obj.master_application and getattr(obj,'SelHandle',None): if not MolDisp.no_connectivity.count(obj.style): nvis = nvis + 1 if MolDisp.spline_styles.count(obj.style) or obj.style.startswith(MolDisp.custom_spline_style_prefix): if obj.style == "WORM" or obj.style.startswith(MolDisp.custom_spline_style_prefix): worm_objects.append(obj) else: spline_objects.append(obj) #print "worm_objects",worm_objects #print "spline_objects",spline_objects #print "nvis",nvis if ( nvis>1 ): if spline_objects: # Update the self.spline_selHnd for all splined atoms self.spline_selHnd = self.molHnd.NewSelection() for spline_obj in spline_objects: #print "spline_obj",spline_obj.name self.molHnd.Select(self.spline_selHnd,STYPE_ATOM,spline_obj.SelHandle.getSelHnd(),SKEY_OR) #self.molHnd.Select(self.spline_selHnd,STYPE_ATOM,"/*/*/*.*/CA:*",SKEY_AND) if worm_objects: self.worm_selHnd = self.molHnd.NewSelection() for spline_obj in worm_objects: #print "spline_obj",spline_obj.name self.molHnd.Select(self.worm_selHnd,STYPE_ATOM,spline_obj.SelHandle.getSelHnd(),SKEY_OR) #self.molHnd.Select(self.worm_selHnd,STYPE_ATOM,"/*/*/*.*/CA:*",SKEY_AND) if not self.all_bonded_atoms: self.all_bonded_atoms = self.molHnd.NewSelection() if not self.all_bonded_atoms_spline: self.all_bonded_atoms_spline = self.molHnd.NewSelection() mode = SKEY_NEW for obj in self.get_dispobj(object_type='MolDisp'): if obj.visible and not obj.master_application and getattr(obj,'SelHandle',None): if MolDisp.connected_styles.count(obj.style) : #print "add to all_bonded_atoms",obj.SelHandle.getLabel() self.molHnd.Select(self.all_bonded_atoms,STYPE_ATOM, \ obj.SelHandle.getSelHnd(),mode) mode = SKEY_OR #print 'ExternalBonds',obj.name,obj.Connectivity.GetNumberOfExternalBonds() if changed_externally_bonded and obj.Connectivity.GetNumberOfExternalBonds()!=0: obj.do_redraw_external = 1 obj.do_update_connectivity = 1 if self.worm_selHnd>0 or self.spline_selHnd>0: tmp_selHnd = self.molHnd.NewSelection() if self.worm_selHnd>0: self.molHnd.Select(tmp_selHnd,STYPE_ATOM,self.worm_selHnd,SKEY_NEW) self.molHnd.Select(tmp_selHnd,STYPE_ATOM,"/*/*/*.*/CA:*",SKEY_AND) self.molHnd.Select(self.all_bonded_atoms_spline,STYPE_ATOM,tmp_selHnd,SKEY_OR) self.splineinfo_worm = GetRibbonOrWormSplineInfo(self.molHnd,self.worm_selHnd,False) if self.spline_selHnd>0: self.molHnd.Select(tmp_selHnd,STYPE_ATOM,self.spline_selHnd,SKEY_NEW) self.molHnd.Select(tmp_selHnd,STYPE_ATOM,"/*/*/*.*/CA:*",SKEY_AND) self.molHnd.Select(self.all_bonded_atoms_spline,STYPE_ATOM,tmp_selHnd,SKEY_OR) self.splineinfo_ribbon = GetRibbonOrWormSplineInfo(self.molHnd,self.spline_selHnd,True) self.molHnd.DeleteSelection(tmp_selHnd) self.changedSplines = [] self.changedConnected = [] self.do_update_all_bonded_atoms = 0 #print 'done update_all_bonded_atoms',time.clock()-start_time #--------------------------------------------------------------------- def update_dependents(self,attribute=''): #--------------------------------------------------------------------- ''' Intercept Dependency.update_dependents in order to prompt all display objects to handle moving ''' #print "MolData update_dependents",attribute if ['reconfigure','edit'].count(attribute): self.apply_edit_secstr() # Do we need to update SAS for obj in self.objinsts: if obj.object_type == 'MolDisp' and \ ['atom_sas','res_sas','atom_buried','res_buried'].count(obj.colour): self.update_sasarea(reapply=1) break if ['transform','reconfigure','edit'].count(attribute): for obj in self.objinsts: obj.handle_moving_data(attribute=attribute,master=self) if obj.object_type == 'MolDisp': obj.label.handle_moving_data(attribute=attribute,master=self) obj.set_extent() obj.do_redraw = 1 #reset the centre/extent Dependency.update_dependents(self,attribute) #---------------------------------------------------------------------- def initialise_MoleculeSelection ( self, CID='',pAtom=None, \ if_monomer=0,if_atom=1): #---------------------------------------------------------------------- import utils #print "initialise_MoleculeSelection CID",CID # Set up the configure statement for a MoleculeSelection widget # assuming it should be initiallised to CID if pAtom: CID = self.molHnd.AtomLabel_atom1(pAtom) #CID = pAtom.GetAtomID()[0] #print "initialise_MoleculeSelection CID",CID if CID: id = self.splitAtomID(CID) #print "id",id if id: # Beware the input id might have a null chain identifier if id[1]: chain = id[1] elif chain_list.count(' '): chain = ' ' #print "chain",chain,"list count",chain_list.count(' ') if if_monomer and self.get_attribute('monomer_list').count(CID): monomer = CID #print "monomer",monomer if if_atom: atom_list = self.get_attribute('atom_list',monomer) atom = id[3] elif chain_list.count(chain): #print "got chain" res_list = self.get_attribute('res_list',chain) if res_list.count(id[2]): res = id[2] #print "res",res if if_atom: atom_list = self.get_attribute('atom_list',res) atom = id[3] config = ['CONFIGURE', ['mol',self.name], ['selection',utils.tclSafe(CID)], ['chain',chain], ['res',res]] if if_atom: config.append( ['atom',atom] ) if if_monomer: config.append( ['monomer',monomer]) return config #------------------------------------------------------------------ def loaddata(self,recentre=1,warnings=1,find_bonds=1,**keywords): #------------------------------------------------------------------ ''' Load data from PDB file and analyse structure ''' errors = [] self.load_warnings = 'Loading file: '+self.filename[2]+'\n' self.molHnd = CMMANManager(RESOURCES().SRS,RESOURCES().CMolBondParams) nChains1 = 0 nChains2 = 0 test1 = Manager() test1.SetFlag(MMDBF_AutoSerials) test1.SetFlag(MMDBF_IgnoreRemarks) test1.SetFlag(MMDBF_IgnoreBlankLines) test1.SetFlag(MMDBF_IgnoreHash) test1.SetFlag(MMDBF_EnforceUniqueChainID) RC = utils.ReadCoorFile(test1,self.filename[2]) if RC == 0: nChains1 = test1.GetNumberOfChains(1) test2 = Manager() test2.SetFlag(MMDBF_AutoSerials) test2.SetFlag(MMDBF_IgnoreRemarks) test2.SetFlag(MMDBF_IgnoreBlankLines) test2.SetFlag(MMDBF_IgnoreHash) RC = utils.ReadCoorFile(test2,self.filename[2]) if RC == 0: nChains2 = test2.GetNumberOfChains(1) if(nChains1!=nChains2): self.molHnd.duplicateChainIDS = True else: self.molHnd.duplicateChainIDS = False self.molHnd.SetFlag(MMDBF_AutoSerials) #self.molHnd.SetFlag(MMDBF_IgnoreRemarks) self.molHnd.SetFlag(MMDBF_IgnoreBlankLines) self.molHnd.SetFlag(MMDBF_IgnoreHash) #self.molHnd.SetFlag(MMDBF_EnforceUniqueChainID) #self.molHnd.SetFlag(MMDBF_AllowDuplChainID) #print "loaddata filename",self.filename[2] #RC1 = self.molHnd.ReadCoorFile(self.filename[2]) RC1 = utils.ReadCoorFile(self.molHnd,self.filename[2]) if RC1 > 0: errors.append(RC1) n_err_line = intp() err_line = self.molHnd.GetInputBuffer (n_err_line ) self.load_errors = GetErrorDescriptionChar ( RC1 ) + \ '\nAt line number' + str(n_err_line.value())+':\n'+err_line + \ '\n ***This may lead to problems with atom selection***' self.load_warnings = self.load_warnings + \ '\n*****Error loading coordinate file******\n' + \ self.load_errors + \ '\n****************************************\n' self.molHnd.SetFlag(MMDBF_IgnoreNonCoorPDBErrors) self.molHnd.SetFlag(MMDBF_IgnoreDuplSeqNum) self.molHnd.SetFlag(MMDBF_IgnoreSegID) self.molHnd.SetFlag(MMDBF_IgnoreElement) self.molHnd.SetFlag(MMDBF_IgnoreCharge) self.molHnd.SetFlag(MMDBF_IgnoreUnmatch) #self.molHnd.SetFlag(MMDBF_IgnoreHash) #self.molHnd.SetFlag(MMDBF_IgnoreRemarks) #self.molHnd.SetFlag(MMDBF_IgnoreBlankLines) #RC2 = self.molHnd.ReadCoorFile(self.filename[2]) RC2 = utils.ReadCoorFile(self.molHnd,self.filename[2]) ''' syminfo = os.path.join(os.environ['CLIBD'],'syminfo.lib') if os.path.exists(syminfo): print 'Loading syminfo' self.molHnd.SetSyminfoLib(syminfo) ''' if RC2 > 0: self.load_warnings = self.load_warnings+ '\nFAILED to load file' return [1,self.load_warnings] else: nat = self.molHnd.GetNumberOfAtoms() if nat <= 0: self.load_warnings = self.load_warnings + '\nNo atoms in the file' if self.filename[2].lower().endswith('.cif') or self.filename[2].lower().endswith('.cif.gz'): return [self.NO_ATOMS_IN_CIF_FILE,self.load_warnings] errors.append(201) #self.molHnd.PDBCleanup ( PDBCLEAN_SERIAL ) udd_duplchids = self.molHnd.GetUDDHandle ( UDR_HIERARCHY,"duplicate_chain_ids" ); if udd_duplchids<=0: udd_duplchids = self.molHnd.RegisterUDInteger(UDR_HIERARCHY,"duplicate_chain_ids" ); if(nChains1!=nChains2): self.molHnd.PutUDData(udd_duplchids,1) else: self.molHnd.PutUDData(udd_duplchids,0) #Cleanup the element names # restore from .ccp4mg - or create new internal data structure MODELINFO().restore(set=self.name_label,filename=self.filename, override=0,create=1) # Apply residue typing self.updateCustomResTypes() self.updateCustomLinks() if find_bonds: #print "Setting customResCIFFiles",self.customResCIFFiles self.molHnd.setCustomResCIFFiles(mmut.map_string_string(self.customResCIFFiles)) output = self.GetMolBonds() if output: self.load_warnings = self.load_warnings + \ '\nMatching residues to library\n\n' + output if not self.molHnd.isSpaceGroup(): self.molHnd.SetSpaceGroup("P1") self.load_warnings = self.load_warnings + '\nNo space group in file - setting to P1' else: spgp = self.molHnd.GetSpaceGroup() if ['R3','R 3'].count(spgp): cell_info = self.molHnd.GetCellInfo() if abs(cell_info[3]-90)<1e-6 and abs(cell_info[4]-90)<1e-6 and abs(cell_info[5]-120)<1e-6: self.molHnd.SetSpaceGroup('H 3') self.load_warnings = self.load_warnings + '\n***Space group R 3 reset to H 3***' rv = self.model_symmetry.check_symmetry(self.filename[2]) if rv[0]: self.load_warnings = self.load_warnings + '\n'+rv[1] if len(rv)>2: errors.append(rv[2]) if not hasattr(self,'originalSymmetry'): self.originalSymmetry = self.getMolHndCell() #self.model_symmetry.load_biomolecule() status,data= MODELINFO().get_info(set=self.name_label, \ info='selection_protocols') #analyse content of molecule self.analyse() # Calculate SS for all models PM('SecStr_param').add_dependent(self.apply_edit_secstr) self.update_ModelInfo_secstr() rv = self.apply_edit_secstr(apply=1) if rv[0]: self.load_warnings = self.load_warnings + '\n' + rv[1] self.CSASArea = None # Recentre if this is the only loaded model if recentre and len(get_dataobj(object_type='MolData'))==1: VW('mainview').recentre = 1 # If we has restored a transform matrix then # apply it now if hasattr(self,'transform_matrix'): vtmat = [] vtran = [] ii = 0 for i in range(0,3): for j in range(0,3): vtmat.append(self.transform_matrix[ii]) ii = ii + 1 vtran.append(self.transform_matrix[ii]) ii = ii + 1 self.molHnd.SetTransform(vtmat,vtran,False) del self.transform_matrix if hasattr(self,'load_animation') and self.load_animation: #print "init MolData load_animation",self.load_animation import Animation #for item in self.load_animation: self.animation = Animation.Animation(parent=self, \ params=self.load_animation) del self.load_animation self.loadTreeModel() self.update_dependents('create') #List warnings if we are not restoring on restart if self.saved_dataparams.has_key('model_symmetry'): self.model_symmetry.setParams(self.saved_dataparams['model_symmetry']) if self.saved_dataparams.has_key('symmetry_mates'): self.model_symmetry.setSymmetryMates(self.saved_dataparams['symmetry_mates']) if self.load_warnings: return [2,self.load_warnings,errors] else: return [0,""] #--------------------------------------------------------------------- def GetMolBonds(self): #--------------------------------------------------------------------- output = self.molHnd.GetMolBonds(bool(self.show_aromatic_rings),bool(self.check_graphs)) #print 'GetMolBonds',output self.apply_edit_bonds() return output #--------------------------------------------------------------------- def loadTreeModel(self): #--------------------------------------------------------------------- import mgTreeView self.treeModel = mgTreeView.AbstractMolData(self.molHnd,self) #--------------------------------------------------------------------- def getMolHndCell(self): #--------------------------------------------------------------------- ''' Return list of reciprocal cell length, angles, volume and orthog code ''' import math import mmdb2 as mmdb import pygl_coord status = 0 sg = self.molHnd.GetSpaceGroup() if not sg: return dict(status=1) rv,xp,yp,zp,a,b,g,volp,codep = self.molHnd.GetCell() # NB GetCell returns 1=OK if not rv: return dict(status=1) return dict(status=0,cell=[ xp,yp,zp,a,b,g],sg=sg,volume=volp,code=codep) #--------------------------------------------------------------------- def setMolHndSymmetry(self,cell=[],sg=''): #--------------------------------------------------------------------- # Save the symmetry in the PDB. The PBD symmetry may be changed if this data # object becomes part of a crystal if not hasattr(self,'originalSymmetry'): self.originalSymmetry = self.getMolHndCell() if cell: self.molHnd.SetCell( \ cell[0],cell[1],cell[2],cell[3],cell[4],cell[5],0) if sg: self.molHnd.SetSpaceGroup(sg) #--------------------------------------------------------------------- def setMasterCrystal(self,crystal='',force=0): #--------------------------------------------------------------------- if crystal != self.masterCrystal or force: self.masterCrystal = crystal if crystal: xtl = get_dispobj(name = crystal) self.setMolHndSymmetry(xtl.cell,xtl.sg) else: #print "setMasterCrystal reverting to",self.originalSymmetry if not self.originalSymmetry.get('status',1): self.setMolHndSymmetry(self.originalSymmetry.get('cell'),self.originalSymmetry.get('sg')) for obj in self.objinsts: obj.setMasterCrystal(crystal) #-------------------------------------------------------------------------- def getSASAreaPM(self): #-------------------------------------------------------------------------- if hasattr(self,'SASAreaPM'): return self.SASAreaPM else: return PM('SASArea_param') #-------------------------------------------------------------------------- def update_sasarea(self,reapply=1,**keywords): #-------------------------------------------------------------------------- if not self.CSASArea: selHnd = -1 sele=self.getSASAreaPM().get('limit_selection') #print "update_sasarea sele",sele if sele != 'all': rv = self.parse_selection(command=sele) #print "update_sasarea parse_selection",rv if rv[0] == 0 and rv[1] > 0: selHnd = rv[1] self.CSASArea = self.molHnd.GetSASArea(selHnd) self.getSASAreaPM().add_dependent(self.update_sasarea) reapply=1 #print "update_sasarea selHnd",selHnd if reapply and self.CSASArea: self.getSASAreaPM().update( self.CSASArea.SetParams ) #MGGUI().StartInterrupt(gui='Stop SAS calculation') #print "update_sasarea",self.nmr_models if self.nmr_models: rv = self.CSASArea.Calculate(0,True) else: rv = self.CSASArea.Calculate(0,False) #MGGUI().EndInterrupt(gui='Stop SAS calculation') if rv: del self.CSASArea self.CSASArea = None else: for obj in self.get_dispobj(object_type='MolDisp'): if ['res_sas','atom_sas','res_buried','atom_buried'].count(obj.colour): obj.do_recolour = 2 return rv #------------------------------------------------------------------------- def clone(self,**keywords): #------------------------------------------------------------------------- if not os.path.exists(self.filename[2]) \ or not os.path.isfile(self.filename[2]): MGGUI().WarningMessage('File no longer exists '+self.filename[2]) return None if keywords and hasattr(keywords,"has_key") and keywords.has_key("name"): m = MolData (filename=self.filename,dataparams=self.dataparams(),name=keywords["name"]) else: m = MolData (filename=self.filename,dataparams=self.dataparams()) rv = m.loaddata() if rv[0]==1: MGGUI().WarningMessage("ERROR loading data from file "+self.filename[2]) m.delete() return None return m #----------------------------------------------------------------- def add_object(self,object_type='MolDisp',visible=1,name='',animation='',params={},selparams={},colparams={},styleparams={},**keywords): #----------------------------------------------------------------- dobj = None if object_type == 'MolDisp': dobj = MolDisp(self.name,visible=visible,params=params,selparams=selparams,colparams=colparams,styleparams=styleparams) if object_type == 'Annotation': import Annotation dobj = Annotation.Annotation(self.name,visible=1,params=params) elif object_type == 'HBonds': import HBonds dobj = HBonds.HBonds(self.name,params=params,selparams=selparams,colparams=colparams,styleparams=styleparams) elif object_type == 'Contacts': import Contacts dobj = Contacts.Contacts(self.name,params=params,selparams=selparams,colparams=colparams,styleparams=styleparams) elif object_type == 'SurfaceDispobj': import SurfaceDispobj dobj = SurfaceDispobj.SurfaceDispobj(self.name,params=params,selparams=selparams,colparams=colparams,styleparams=styleparams) return dobj #----------------------------------------------------------------- def add_animation(self,filelist=[]): #----------------------------------------------------------------- if self.animation: self.animation.delete() import Animation self.animation = Animation.Animation(parent=self,filelist = filelist) return self.animation #----------------------------------------------------------------- def handle_program_exit(self): #----------------------------------------------------------------- ''' Tidy up on program exit ''' # save .ccp4mg file MODELINFO().save(set=self.name_label,filename=self.filename) #Remove a animation legend if hasattr(self,'animation') and self.animation.legend_obj: self.animation.legend_obj.delete() #--------------------------------------------------------------------- def copy_display(self,copy_from='',filename='', clear=0,**keywords): #--------------------------------------------------------------------- #print 'MolData.copy_display',copy_from ''' This is left in as reminder of v1.0 option to load picture style from pickle file if filename: status = HISTORY().load_pickle_file(filename=filename,DIR_filename=DIR_filename) #print "load_pickle_file status",status if not status or not status.has_key('Data_list') : MGGUI().WarningMessage('No model status found in the file') return 1 if len(status['Data_list'])==1: copy_dataobj = status[status['Data_list'][0]] shadow = 1 else: model_menu = [] for item in status['Data_list']: if status.has_key(item) and status[item].object_type == 'MolData': model_menu.append(item) MGGUI().CreateGUIWindow ('copy_from_file_model',self, [ ['TITLE','Copy display from status file'], ['OFFSET','display_table'], ['RETURN_METHOD','copy_display', ['RETURN_LIST','file_model']], ['PARAM','file_model', ['TYPEDEF','menu',model_menu,model_menu]], ['DISPLAY','WINDOW', ['LINE', ['LABEL','Copy from model'], ['WIDGET','file_model']], ['BUTTONS',['ok',['LABEL','Apply']],['dismiss','CLOSE']] ] ]) self.copy_from_status = status return ''' if copy_from: copy_dataobj = data(name=copy_from) if not copy_dataobj: return [1,'Error finding data object '+copy_from] copy_dataobj_shadow = dataobj.DataObjShadow() copy_dataobj_shadow.save(copy_dataobj) #Zap current display objects if clear: del_list=[] for obj in self.objinsts: del_list.append(obj) for obj in del_list: obj.delete() # Use the base class update_data_status which only updates # the display objects and not any other dataobj.DataObj.update_data_status(self,copy_dataobj_shadow,clear=clear) return [0,''] return [1,''] #---------------------------------------------------------------------- def save_file(self,filename=''): #---------------------------------------------------------------------- if os.path.splitext(filename)[1] == '.cif': rv = self.molHnd.WriteCIFASCII(filename) else: filename = os.path.splitext(filename)[0]+'.pdb' rv = self.molHnd.WritePDBASCII(filename) #print 'MolData.save_file',filename,rv self.setFilename(filename) # Unset any transform - do not apply an undo transformation self.molHnd.UnSetTransform(False) return rv #---------------------------------------------------------------------- def list_data_file(self,list_data='all',filename='',DIR_filename='', file_format='PDB',**keywords): #---------------------------------------------------------------------- ''' list_data = 'visible' => list only the atoms in visible display objects list_data = MolDisp.name => list only the atoms MolDisp or if filename is set then list the data in that file or list self.filename ''' if file_format == 'PDB': save_ext = '.pdb' else: save_ext = '.cif' #print "list_data_file list_data",list_data if list_data == 'all' and os.path.splitext(self.filename[1]) == save_ext: DataObj.list_data_file(self,filename=self.filename[2]) else: if ['visible','all'].count(list_data): selHnd = self.molHnd.NewSelection() if list_data == 'visible': dispobj_list = self.get_dispobj(object_type='MolDisp') for dispobj in dispobj_list: if dispobj.visible: self.molHnd.Select(selHnd,STYPE_ATOM,dispobj.selHnd,SKEY_OR) else: self.molHnd.SelectAtoms(selHnd, 0,"*",ANY_RES,"*",ANY_RES,"*", \ "*","*","*","*",SKEY_OR ) else: dispobj = self.get_dispobj(name=list_data) if not dispobj: return [1,'ERROR in MolData.list_data_file'] selHnd = dispobj.SelHandle.getSelHnd() #Keep unique index for each selection list for this model in # this session #(DatObj.list_data_file() has default index 0 for all data i.e. displaying the whole file) if not hasattr(self,'list_data_file_index'): self.list_data_file_index = 0 self.list_data_file_index = self.list_data_file_index + 1 # Get a name for temporary PDB/CIF file import utils if filename: filename = utils.get_filename(DIR_filename,filename) else: filename = os.path.join(utils.environScratch(), \ utils.fileRoot(self.filename[1])+'_sele_'+ str(self.list_data_file_index)+save_ext) #print "list_data_file filename",filename if os.path.exists(filename): os.remove(filename) RC = self.molHnd.WriteSelection(selHnd,filename,file_format) if ['visible','all'].count(list_data): self.molHnd.DeleteSelection(selHnd) if RC: return [1,'ERROR writing temporary file '+filename] else: return [0,filename] #------------------------------------------------------------------- def transform(self,glwidget): #------------------------------------------------------------------- ''' Handle mouse input to translate objects ''' import pygl_coord import utils #print 'MolData.transform', glwidget.transformDeltaMode() if glwidget.transformDeltaMode() == 'translate': vtrans = glwidget.worldTranslate() #print "MolData.transform",vtrans vrot=[1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0] self.molHnd.SetTransform(vrot,vtrans,False) else: #Handle rotation not sorted vrotmat = glwidget.worldRotate().matrixVector() vtrans = [0.0,0.0,0.0] vrot = [] ii = -1 for i in [0,1,2]: for j in [0,1,2]: ii = ii + 1 vrot.append(vrotmat[ii]) ii = ii + 1 self.molHnd.SetTransform(vrot,vtrans,False) # Moving cursor in x-direction - expect rot about y axis ''' axes = [ [0.0,1.0,0.0], [1.0,0.0,0.0], [0.0,0.0,1.0] ] i = -1 for rot in [rotx,roty,rotz]: i = i + 1 if rot: frot = utils.safeFloat(rot,0.0) cart = pygl_coord.Cartesian(axes[i]) cartnew = qmat * cart axis = [ cartnew.get_x(),cartnew.get_y(), cartnew.get_z() ] #print "axis",axis self.molHnd.SetTransform(frot,axis,-1) ''' self.update_dependents(attribute='transform') #-------------------------------------------------------------------- def draw(self): #-------------------------------------------------------------------- for obj in self.objinsts: obj.do_redraw = 1 obj.draw() #-------------------------------------------------------------------- def handle_transform_popup(self,transform_select='',**keywords): #-------------------------------------------------------------------- #Atom popup for the 'live' moving model #Enables setting the centre of rotation #print "handle_transform_popup",transform_select if transform_select: from atom_util import inta molobj,dispobj,atomptr = ATOMPICKING().get_last_picked('atom') if transform_select == 'SSE': mask = inta(7) for i in range(0,7): mask[i] = 1 import string sub = string.strip(self.molHnd.ListSecStructure(mask,atomptr)) if sub: sel = string.split(sub)[1] else: sel = '' else: mask = inta(9) py_mask = [0,1,1,1,1,1,1,1,0] for i in range(0,9): mask[i]=py_mask[i] selected_atom = molobj.molHnd.AtomLabel_mask(atomptr,mask) del mask sel = self.convertAtomID ( out =transform_select , \ atomID = selected_atom) #print "sel",sel if not sel: return selHnd = self.molHnd.NewSelection() self.molHnd.Select (selHnd,STYPE_ATOM,sel,SKEY_NEW) self.transform_centre = sel self.molHnd.SetTransform(0.0,[1.0,0.0,0.0],selHnd) self.molHnd.DeleteSelection(selHnd) return else: # Define a portion of the pop-up menu to appear when # the user picks an atom molobj,dispobj,atomptr = ATOMPICKING().get_last_picked('atom') if molobj != self: return ['','',''] params = [ ['RETURN',self.name_string()+'.handle_transform_popup'], ['PARAM','transform_select', ['LABEL','Rotate around this'], ['TYPEDEF','menu',['atom','residue','SSE','chain','all'], ['atom','residue','SSE','chain','all']], ['INITIAL','']] ] display = [ ['pr','transform_select']] return ['',params,display] #--------------------------------------------------------------------- def findDispobjContainingAtom(self,atm_ptr=None,object_type='MolDisp'): #--------------------------------------------------------------------- ''' Find the first MolDisp containing the atom atm_ptr Used when need to stick a label on the display ''' #print "atm_ptr",atm_ptr dispobj = None ii = 0 dobj_list = self.get_dispobj(object_type=object_type) #print "dobj_list",dobj_list while not dispobj and ii < len(dobj_list): selHnd = dobj_list[ii].SelHandle.getSelHnd() #print "ii,selHnd",ii,selHnd if selHnd >0 and atm_ptr.isInSelection(selHnd): dispobj = dobj_list[ii] ii = ii + 1 return dispobj #------------------------------------------------------------------ def handle_edit(self,_edit='', exit='', nsecstr='',\ edit_secstr_secstr='',edit_secstr_first='',edit_secstr_last='', \ restype_res='',restype_type='',restype_alias='', \ monlib='',DIR_monlib='', dsspfile='',DIR_dsspfile='', secstrfile='',**keywords): #------------------------------------------------------------------ import types #print "handle_edit restype_res",restype_res,restype_type,exit # Draw the GUI if _edit == 'restype': #print "status,sel_prot",status,sel_prot length = 0 restype_res = [] restype_alias = [] restype_type = [] #Get the residue name aliases status,alias= MODELINFO().get_info(set=self.name_label, \ info='residue_aliases') #print "status,alias",status,alias if not status: for key,value in alias.items(): restype_res.append(key) restype_alias.append(value) restype_type.append('') status,sel_prot= MODELINFO().get_info(set=self.name_label, \ info='selection_protocols') #print "sel_prot",sel_prot if not status: for type in MolData.restype_alias: if sel_prot.has_key(type) and sel_prot[type].has_key('ORDER'): for item in sel_prot[type]['ORDER']: if restype_res.count(item): ii = restype_res.index(item) restype_type[ii] = type else: restype_type.append(type) restype_res.append(item) restype_alias.append('') length = len(restype_res) if status or length == 0: restype_res = [''] restype_alias = [''] restype_type=[''] length=1 MGGUI().CreateGUIWindow('edit_restype_'+self.name,self, [ ['TITLE','Edit residue type assignment for '+self.name_label], ['ICON','Edit'], ['HELP','atom_typing#residue_types'], ['RETURN_METHOD','handle_edit', ['RETURN_LIST', ['edit_restype::res',['ALIAS','restype_res']], ['edit_restype::alias',['ALIAS','restype_alias']], ['edit_restype::type',['ALIAS','restype_type']]]], ['DISPLAY','WINDOW', ['LINE',['LABEL','For residue types not recognised by the monomer','-italic']], ['LINE',['LABEL','library enter the name of residue and either','-italic']], ['LINE',['LABEL','the equivalent library name and/or the residue type','-italic']], ['EXTENDING_FRAME','edit_restype', ['TITLE_LINE', ['LABEL','Name'], ['LABEL','library name'], ['LABEL','type']], ['LENGTH',length], ['CONFIGURE',['gui_label','residue type'], ['res',restype_res], ['alias',restype_alias], ['type',restype_type]], ['PARAM','type', ['TYPEDEF','menu',MolData.restype_menu,MolData.restype_alias], ['INITIAL',MolData.restype_alias[0]]], ['PARAM','res', ['TYPE','_text'], ['INITIAL','']], ['PARAM','alias', ['TYPE','_text'], ['INITIAL','']], ['DISPLAY', ['LINE', ['WIDGET','res'], ['WIDGET','alias'], ['WIDGET','type']]] ], ['BUTTONS',['ok',['LABEL','Apply']], ['dismiss','CLOSE']] ] ] ) elif isinstance(restype_res,types.ListType) and exit == 'ok': # Set up sel_prot dictionary with items for the # 'standard' residue types sel_prot = {} for type in Selection.restype_alias: sel_prot[type]={} sel_prot[type]['ORDER']=[] # Load sel_prot with the residue type info from the GUI for ii in range(len(restype_res)): if not sel_prot[restype_type[ii]]['ORDER'].count(restype_res[ii]): sel_prot[restype_type[ii]]['ORDER'].append(restype_res[ii]) # For each 'standard' type either add or delete from ModelInfo # dependent on whether there is an info in the sel_prot item for type in MolData.restype_alias: if sel_prot[type]['ORDER']: ret = MODELINFO().add_info(set=self.name_label, \ info='selection_protocols',key=type,value=sel_prot[type]) else: MODELINFO().delete_info(set=self.name_label, \ info='selection_protocols',key=type) # Clear out any saved residue aliases MODELINFO().delete_info(set=self.name_label, \ info='residue_aliases',key='*') # Save the residue name alias info for ii in range(len(restype_res)): if restype_res[ii] and restype_alias[ii]: #print "saving alias",restype_res[ii],restype_alias[ii] #aliases[restype_res[ii]] = restype_alias[ii] ret = MODELINFO().add_info(set=self.name_label, \ info='residue_aliases',key=restype_res[ii],value=restype_alias[ii]) # Apply residue typing self.updateCustomResTypes() # update secondary structure self.apply_edit_secstr() #redo bonding # as per loaddata # Get bonds - use any monomer library associated with this PDB status,data= MODELINFO().get_info(set=self.name_label, \ info='monomer_library') if data.has_key('filename'): import utils monlib = utils.get_filename(data['filename'][0],data['filename'][1]) else: monlib = '' output = self.molHnd.GetMolBonds(monlib) #print "output from GetMolBonds",output self.load_warnings = self.load_warnings + \ '\nReassigning atom types and bonding..\n\n' + output # Redo analyse assuming res types have been changes self.analyse() # Redo selection of all display objects obj_list = self.get_dispobj(object_type='MolDisp') #print "reapply_selection obj_list",obj_list for obj in self.get_dispobj(object_type='MolDisp'): obj.reapply_selection = 1 elif _edit == 'monlib': status,data= MODELINFO().get_info(set=self.name_label, \ info='monomer_library') if data.has_key('filename'): import utils monlib = utils.get_filename(data['filename'][0],data['filename'][1]) else: monlib = '' MGGUI().CreateGUIWindow ('monlib',self, [ ['RETURN_METHOD','handle_edit'], ['TITLE','Select monomer library file'], ['OFFSET','display_table'], ['PARAM','monlib', ['TYPE','_cif_file'], ['INITIAL',monlib]], ['DISPLAY','SELECTFILE', ['FILE','monlib','-format','CIF','-filter','*.cif']] ] ) elif monlib and exit == '1': import utils ret = MODELINFO().add_info(set=self.name_label, \ info='monomer_library',key='filename',value=[DIR_monlib,monlib]) filn=utils.get_filename(DIR_monlib,monlib) output = self.molHnd.GetMolBonds(filn) self.load_warnings = self.load_warnings + \ '\n\nRevised atom typing...\n\n' + output elif _edit == 'list_charges': self.molHnd.LoadCharge('surface_potential_charge') text = self.molHnd.PrintCharges() import string textlist = string.split(text,"\n") MGGUI().CreateGUIWindow ('list_charges',self,[ ['TITLE',"Assigned charges"], ['HELP','surfaces#charge_assignment'], ['ICON','Data'], ['RETURN_METHOD','handle_edit', ['MODE','GUI']], ['OBJECT','data', ['TYPE','ListData'], ['RETURN_METHOD','handle_edit', ['MODE','GUI']], ['CONFIGURE',['height','20'], ['width','60'], ['pick_dataobj',self.name], ['font','fixed'], ['text_list',textlist]]], ['DISPLAY','WINDOW', ['MESSAGE'], ['SUBFRAME', [] , [ ['LINE', ['LABEL','Double click on atom name to centre on atom','-italic']]]], ['DRAW','data'], ['BUTTONS',['dismiss0','CLOSE',['LABEL','Close']]] ] ]) #------------------------------------------------------------------ def edit_secstr_popup(self,**keywords): #------------------------------------------------------------------ #print "edit_secstr_popup",keywords at_pick = ATOMPICKING() molobj,dispobj,atomptr = at_pick.get_last_picked('atom') #print "molobj,dispobj",molobj.name,dispobj.name,molobj,self if molobj != self: return ['','',''] #mask = inta(7) #for i in range(0,7): mask[i] = 1 #sub = string.strip(molobj.molHnd.ListSecStructure(mask,atomptr)) # if onelet.count(sub[0]): # sse = sse_name[onelet.index(sub[0])]+sub[1:] #else: # sse = '' if self.interactive_edit_secstr: range = self.getResidueID(self.interactive_edit_secstr[0], atomptr) last_resid = range[2] else: last_resid = self.getResidueID(atomptr) params = [ ['RETURN',self.name_string()+'.handle_edit_secstr_popup'], ['PARAM','start_range', ['TYPEDEF','menu',MolData.secstr_menu,MolData.secstr_alias], ['INITIAL',''], ['LABEL','Set sec structure for '+last_resid+' to']] ] display = [ ['pr','start_range'] ] if self.interactive_edit_secstr: sse = MolData.secstr_menu[MolData.secstr_alias.index(self.interactive_edit_secstr[1])] params.append( ['PARAM','end_range', ['TYPE','_logical'], ['INITIAL',''], ['LABEL','Set '+range[0]+' '+sse ]]) display.append(['com','end_range']) return ['',params,display] #----------------------------------------------------------------- def handle_edit_secstr_popup (self,start_range='',end_range='',**keywords): #----------------------------------------------------------------- #print "handle_edit_secstr_popup",start_range,'*',end_range #print "interactive_edit_secstr",self.interactive_edit_secstr at_pick = ATOMPICKING() molobj,dispobj,atomptr = at_pick.get_last_picked('atom') resid = self.getResidueID(atomptr) #print "molobj,dispobj",molobj.name,dispobj.name,molobj,self if molobj != self: return ['','',''] add = 0 edit_secstr_first=[]; edit_secstr_last=[];edit_secstr_secstr=[] for item in self.edit_secstr: edit_secstr_first.append(item[0]) edit_secstr_last.append(item[1]) edit_secstr_secstr.append(item[2]) if start_range: self.interactive_edit_secstr=[atomptr,start_range] if not edit_secstr_first[-1] and not edit_secstr_last[-1]: edit_secstr_first[-1]= resid edit_secstr_secstr[-1] = start_range else: edit_secstr_first.append(resid) edit_secstr_last.append('') edit_secstr_secstr.append(start_range) add = 1 elif end_range: if edit_secstr_first[-1] == self.getResidueID(self.interactive_edit_secstr[0]) and edit_secstr_last[-1] == '': edit_secstr_last[-1] = resid self.interactive_edit_secstr=[] self.edit_secstr = [] for i in range(len(edit_secstr_secstr)): if edit_secstr_first[i] or edit_secstr_last[i]: self.edit_secstr.append([edit_secstr_first[i], \ edit_secstr_last[i],edit_secstr_secstr[i]]) #ModelInfo.insts.add_info(set=self.name_label,info='edit_secstr', # key='edit_secstr',value=self.edit_secstr) self.apply_edit_secstr(apply=1) MGGUI().UpdateGUIWindow('edit_secstr_'+self.name, [ ['OBJECT','edit_secstr', ['CONFIGURE',['add',str(add)], ['secstr',edit_secstr_secstr], ['first::selection',edit_secstr_first], ['last::selection',edit_secstr_last]] ] ]) #------------------------------------------------------------------ def update_ModelInfo_secstr(self): #------------------------------------------------------------------ # Test for pre-2.0 style secstr info - convert to new style and update the ModelInfo status,data = MODELINFO().get_info(set=self.name_label,info= 'edit_secstr',key='edit_secstr') if not status and data.has_key('edit_secstr'): seli_command = [] secstr= [] import model_selection for item in data: seli_list = self.interpretRanges(item[0],item[1]) seli_command.append(seli_list[1]) if not seli_command or not MolData.secstr_alias.count(item[2]): break secstr.append(item[2]) #print 'MolData.update_ModelInfo_secstr',seli_command,secstr if secstr: MODELINFO().add_info(set=self.name_label,info= 'edit_secstr',key='selection_command',value=seli_command) MODELINFO().add_info(set=self.name_label,info= 'edit_secstr',key='secstr',value=secstr) MODELINFO().delete_info(set=self.name_label,info= 'edit_secstr',key='edit_secstr') #------------------------------------------------------------------ def setDSSPFile(self,filn): #------------------------------------------------------------------ self.DSSP_file = filn self.apply_edit_secstr() #------------------------------------------------------------------ def apply_edit_secstr(self,apply=1,ParamsManager=None,**keywords): #------------------------------------------------------------------ if not hasattr(self,'molHnd'): return selindexp = pygl_coord.intp() load_err = 1 if hasattr(self,'DSSP_file'): print self.DSSP_file self.DSSP_file[2]= get_filename(self.DSSP_file[0],self.DSSP_file[1]) #print "DSSP_file",self.DSSP_file if os.path.exists(self.DSSP_file[2]): load_err = self.LoadDSSP(self.DSSP_file[2]) npdbsecs = 0 if load_err and npdbsecs==0: flagBulge = PM('SecStr_param').params['flagBulge'] amino_acid = MODELINFO().get_names_string(key='amino_acid', \ set=self.name_label) pm = PM('SecStr_param') if pm and pm.params.has_key('min_helix_length'): minHelixResidues = pm.params['min_helix_length'] else: minHelixResidues = 4 for model in range(1,self.molHnd.GetNumberOfModels()+1): if self.molHnd.GetModel(model): rv = self.parse_selection(command='/'+str(model)+'/*/'+amino_acid) if not rv[0]: self.molHnd.GetModel(model).CalcSecStructure(bool(flagBulge),rv[1]) self.molHnd.RemoveSmallHelices(model,minHelixResidues) self.molHnd.DeleteSelection(rv[1]) else: self.molHnd.GetModel(model).CalcSecStructure(bool(flagBulge)) self.molHnd.RemoveSmallHelices(model,minHelixResidues) if self.molHnd.GetNumberOfSecStructure(SSE_Strand)+self.molHnd.GetNumberOfSecStructure(SSE_Bulge) + self.molHnd.GetNumberOfSecStructure(SSE_Helix) == 0: # MG found no secondary structure, try HELIX/SHEET cards. npdbsecs = self.molHnd.ApplyPDBSecStructure(self.first_nmr_model) nChanged = 0 if apply: secstr = [] status,data = MODELINFO().get_info(set=self.name_label,info= 'edit_secstr') #print 'MolData.apply_edit_secstr',status,data if not status and data.has_key('selection_command') and data.has_key('secstr'): selection_command = data['selection_command'] secstr = data['secstr'] if secstr: resSelHnd = self.molHnd.NewSelection() selResidues = newPPCResidue() for ii in range(len(secstr)): if not MolData.secstr_alias.count(secstr[ii]): break # beware interpretRanges might return seletion of form 'range A/1 B/10' # which can not be interpreted by mmdb - so use parse_selection status,selHnd = self.parse_selection(command=selection_command[ii]) if status: break self.molHnd.Select(resSelHnd,STYPE_RESIDUE,selHnd,SKEY_NEW) #nselRes =self.molHnd.GetSelIndex(resSelHnd,selResidues) selResidues = mmut.GetResidueSelIndex(self.molHnd,resSelHnd,selindexp) nselRes = selindexp.value() #print "MolData.apply_secstr nselRes",selection_command[ii],nselRes if nselRes > 0: SSE = inta(1) SSE = MolData.secstr_enum[MolData.secstr_alias.index(secstr[ii])] nChanged = nChanged + nselRes for ir in range(0,nselRes): pcres = getPCResidue(selResidues,ir) pcres.SSE = SSE self.molHnd.DeleteSelection(selHnd) self.molHnd.DeleteSelection(resSelHnd) # Redraw all display objects for obj in self.get_dispobj(object_type = 'MolDisp'): #print "do_redraw",obj if hasattr(obj,'model_colour'): if ['secstr','rules','blend'].count(obj.model_colour.colour_mode): # Force the CMolColour class to redo colour obj.model_colour.CMolColour.SetMode(1) obj.do_recolour = max(2,obj.do_recolour) obj.model_colour.do_recolour = max(2,obj.do_recolour) if ['SPLINE','WORM','FATWORM'].count(obj.style): obj.do_redraw=1 if nChanged: return [1,"WARNING: The model secondary structure has been edited by the user"] else: return [0,''] #----------------------------------------------------------------- def apply_edit_bonds(self): #----------------------------------------------------------------- status,edit_bonds = MODELINFO().get_info( \ set=self.name_label,info= 'edit_bonds',key='edit_bonds') #print "apply_edit_bonds get_info",status,edit_bonds if status or not edit_bonds.has_key('edit_bonds'): return if hasattr(self,'current_edit_bonds') and self.current_edit_bonds: current_edit_bonds = self.current_edit_bonds else: current_edit_bonds = [] # Has any action been removed from the list? # If so then reverse the action #print "current_edit_bonds",current_edit_bonds for item in current_edit_bonds: if not edit_bonds['edit_bonds'].count(item): p_atom1 = self.interpretAtomID(self,item[0],force_one_atom=1) p_atom2 = self.interpretAtomID(self,item[1],force_one_atom=1) if not p_atom1 or not p_atom2: pass elif item[2] == 'delete': self.molHnd.EditBonds(1,p_atom1,p_atom2) elif item[2] == 'add': self.molHnd.EditBonds(-1,p_atom1,p_atom2) new_edit_bonds = [] for item in edit_bonds['edit_bonds']: if not current_edit_bonds.count(item): p_atom1 = self.interpretAtomID(self,item[0],force_one_atom=1) p_atom2 = self.interpretAtomID(self,item[1],force_one_atom=1) rv = 1 if not p_atom1: print "Attempting to edit bonds - no atom called",item[0] elif not p_atom2: print "Attempting to edit bonds - no atom called",item[1] elif item[2] == 'add': rv = self.molHnd.EditBonds(1,p_atom1,p_atom2) elif item[2] == 'delete': rv = self.molHnd.EditBonds(-1,p_atom1,p_atom2) #print "applying ",item,p_atom1,p_atom2,rv if not rv: new_edit_bonds.append(item) else: new_edit_bonds.append(item) self.do_update_all_bonded_atoms = 1 for obj in self.get_dispobj(object_type='MolDisp'): obj.do_update_connectivity = 1 obj.do_redraw = 1 self.current_edit_bonds = new_edit_bonds #print 'apply_edit_bonds current_edit_bonds',self.current_edit_bonds return #----------------------------------------------------------------- def updateCustomResTypes(self): #----------------------------------------------------------------- status,sel_prot= MODELINFO().get_info(set=self.name_label, \ info='selection_protocols') #print "updateCustomResTypes status,sel_prot",status,sel_prot if not status: clear = True; for i in range(len(MolData.restype_alias)): restype = MolData.restype_alias[i] if sel_prot.has_key(restype) and sel_prot[restype].has_key('ORDER'): for item in sel_prot[restype]['ORDER']: #print 'updateCustomResTypes calling SetCustomRestype',item,int(MolData.restype_code[i]) rv = self.molHnd.SetCustomRestype(item,int(MolData.restype_code[i]),clear) clear = False # Load the user defined residue name aliases status,alias= MODELINFO().get_info(set=self.name_label, \ info='residue_aliases') if not status: if alias: clear = True for key,value in alias.items(): rv = self.molHnd.SetCustomResSynonym(key,value,clear) #print "SetCustomResSynonym rv",key,value,rv clear = 0 else: #Clear all ResSynonyms rv = self.molHnd.SetCustomResSynonym('','',True) #----------------------------------------------------------------- def apply_edit_links(self): #----------------------------------------------------------------- self.updateCustomLinks() output = self.GetMolBonds() #print 'apply_edit_links',output self.redraw_all_objects() #----------------------------------------------------------------- def updateCustomLinks(self): #----------------------------------------------------------------- # FIXME -- TOTALLY UNIMPLEMENTED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # This is mechanism for user to define links that are not in the monomer library # There are (at least) a couple of weaknesses - # - each model has its own defined links which when added to CMGSBase will be applied to all models # - there is no way to delete links in CMGSBase so could retain mistaken definitions (restarting # program will get round this status,edit_links = MODELINFO().get_info( set=self.name_label,info= 'edit_links',key='edit_links') #print 'MolData.updateCustomLinks',status,edit_links if edit_links.has_key('edit_links'): for item in edit_links['edit_links']: RESOURCES().CMGSBase.AddLink(item[0], item[1], item[2], item[3]) #------------------------------------------------------------------ def set_save_format(self): #------------------------------------------------------------------ pass #------------------------------------------------------------------- def get_centre(self,selection='',selHnd=''): #------------------------------------------------------------------- # try interpreting the selection and derive a selHnd if selection != "": rv = self.parse_selection([None,selection]) #print 'MolData.get_centre rv',rv,'selection',selection if rv[0] == 0 and rv[1] > 0: if_del_selhnd = 1 selHnd = rv[1] else: if not selHnd: return [1,(0.0,0.0,0.0)] else: if_del_selhnd = 0 # Get the Centre of Mass of selected atoms retval,extent = self.get_extent(selHnd) if retval: return [1,(0.0,0.0,0.0)] com = [] for ii in [0,1,2]: com.append(( extent[ii] + extent[ii+3] ) / 2.0) #print "MolData.get_centre com",com return [0,com] #----------------------------------------------------------------------- def get_extent ( self,selHnd): #----------------------------------------------------------------------- extent = self.molHnd.Extent(selHnd) if len(extent)>0: retval = 0 else: retval = 1 return [retval,extent] #----------------------------------------------------------------------- def interpret_selobj(self,selobj): #----------------------------------------------------------------------- # Is the object name one of the display objects? if self.objnames.count(selobj) == 1: ii = self.objnames.index(selobj) #print "ii",ii obj = self.objinsts[ii] #print "obj",obj selHnd = obj.selHnd # .. or is it a user defined selection object retval,user_selection=MODELINFO().get_info( \ set=self.name_label,info='user_selection',key=selobj) if not retval and user_selection.has_key(selobj): selection = user_selection[selobj] if (len(self.objnames) == 0): retval = 3 else: i = 0 for dobj in self.objinsts: if selobj == dobj.alias:obj = dobj if obj == "": obj = self.objinsts[0] #------------------------------------------------------------------ def movie_interpolation(self,initial_status=None,final_status=None, \ fraction=0.0,step='',**keywords): #------------------------------------------------------------------ #print "model movie_interpolation",fraction if hasattr(self,'animation'): import Animation if step != 0: self.animation.next_frame() if Animation.AnimationParamsManager().get('update_properties'): self.update_dependents('reconfigure') else: self.update_dependents('transform') if initial_status and final_status: if initial_status.dataparams.has_key('transform_matrix') or \ final_status.dataparams.has_key('transform_matrix'): if initial_status.dataparams.has_key('transform_matrix'): ivMat = initial_status.dataparams['transform_matrix'] else: ivMat = [ 1.0, 0.0, 0.0, 0.0, \ 0.0, 1.0, 0.0, 0.0, \ 0.0, 0.0, 1.0, 0.0, \ 0.0, 0.0, 0.0, 1.0 ] if final_status.dataparams.has_key('transform_matrix'): fvMat = final_status.dataparams['transform_matrix'] else: fvMat = [ 1.0, 0.0, 0.0, 0.0, \ 0.0, 1.0, 0.0, 0.0, \ 0.0, 0.0, 1.0, 0.0, \ 0.0, 0.0, 0.0, 1.0 ] #print "model movie_interpolation",ivMat,fvMat if ivMat != fvMat: import pygl_coord iQuat = pygl_coord.Quat(pygl_coord.matrix(4,4,ivMat)) fQuat = pygl_coord.Quat(pygl_coord.matrix(4,4,fvMat)) #rotQuat = (iQuat*(1.0-fraction))+(fQuat*fraction) rotMat = ((iQuat*(1.0-fraction))+(fQuat*fraction)).getMatrix() transMat = pygl_coord.matrix(4,4, \ [ 0.0, 0.0, 0.0,(((1.0-fraction)*ivMat[3])+(fraction*fvMat[3])), \ 0.0, 0.0, 0.0,(((1.0-fraction)*ivMat[7])+(fraction*fvMat[7])), \ 0.0, 0.0, 0.0,(((1.0-fraction)*ivMat[11])+(fraction*fvMat[11])), \ 0.0, 0.0, 0.0, 0.0 ] ) rotMat=rotMat+transMat self.molHnd.SetTransform(rotMat,True) self.update_dependents('transform') DataObj.movie_interpolation(self,initial_status=initial_status, \ final_status=final_status,fraction=fraction,step=step) #-------------------------------------------------------------------------- def copy_data_files(self,project='',dir='',overwrite=1,extra_files=[]): #-------------------------------------------------------------------------- if hasattr(self,'animation') and self.animation: if self.animation.file_format == 'NMR_models': if os.path.exists(self.animation.filename[2]): extra_files.append(self.animation.filename[2]) elif self.animation.file_format == 'multiple_PDBs': for iframe in range(self.animation.frame_range[0],self.animation.frame_range[1]): path = self.animation.filebase[0]+str(iframe)+ \ self.animation.filebase[1] if os.path.exists(path): extra_files.append(path) if project: newfile = os.path.join(dir,os.path.split(self.animation.filename[2])[1]) self.animation.filename=[self.animation.filename[0],project,newfile] #print "model copy_data_files",extra_files return DataObj.copy_data_files(self,project=project,dir=dir, \ overwrite=overwrite,extra_files=extra_files) #----------------------------------------------------------------- def LoadDSSP ( self, filename='',**keywords ) : #----------------------------------------------------------------- # Read DSSP SecStr output file import string selindexp = pygl_coord.intp() #filename = get_filename(DIR_dsspfile,dsspfile) f = openFile(filename,'r') if not f: return 1 lines=f.readlines() if len(lines)<1: f.close() return 1 ii = 0 match = 0 while match == 0 and ii0: match = 1 ii=ii+1 else: ii = ii +1 if ii == len(lines): return 2 pMdl = self.molHnd.GetModel(1) while ii 0: pRes = getPCResidue(residues,0) #pRes = pMdl.GetResidue0(chain,resid,ins) if pRes and MolData.secstr_code_dssp.count(dssp): sse = MolData.secstr_enum_dssp[MolData.secstr_code_dssp.index(dssp)] pRes.SSE = sse ii=ii+1 f.close() return 0 #------------------------------------------------------------------ def get_open_schemes(self,info='user_selection',context='generic'): #------------------------------------------------------------------ schemes = [] if info == 'user_selection': for obj in self.objinsts: if ['MolDisp'].count(obj.object_type): selhandle_list = [ obj.SelHandle] elif ['SurfaceDispobj','HBonds','Contacts'].count(obj.object_type): selhandle_list = [ obj.SelHandle1, obj.SelHandle2] else: selhandle_list = [] for selh in selhandle_list: if selh.selparams['select'] == 'selection_scheme': if not schemes.count(selh.selparams['selection_scheme']): schemes.append(selh.selparams['selection_scheme']) #elif info == 'user_colour_schemes': # for obj in self.objinsts: # if ['MolDisp','SurfaceDispobj'].count(obj.object_type): # if obj.model_colour.colour_mode == 'rules' and hasattr(obj,'user_scheme') and len(obj.user_scheme)>=2 and obj.user_scheme[1]==context and (not schemes.count(obj.user_scheme[0])): # schemes.append(obj.user_scheme[0]) return schemes #------------------------------------------------------------------- def redraw_all_objects(self): #------------------------------------------------------------------- # Force redraw of all display objects after model editted # beware - about to delete items from list dispobj_list = self.get_dispobj() #print "redraw_all_objects",dispobj_list for obj in dispobj_list: obj.set_reapply_selection() obj.do_update_connectivity = 1 # Redo the connectivity self.do_update_all_bonded_atoms = 1 self.update_all_bonded_atoms() #----------------------------------------------------------------- def resetSelHandles(self): #----------------------------------------------------------------- # Forces reselection of all mmdb selection handles - necessary # if number of atoms in model has changed (eg in handling symmetry) for obj in self.objinsts: for item in ['SelHandle','SelHandle1','SelHandle2']: selh = getattr(obj,item,None) if selh: selh.setSelHnd(-1) # Functions to create and return the ParamsManager for analysis # classes related to MolData #--------------------------------------------------------------- def SecStructureParamsManager(): #--------------------------------------------------------------- import services pm = services.ParamsManager ( name='SecStr_param', title='Secondary structure', picture_definition = 1, gui =['flagBulge','min_helix_length'], default = { 'flagBulge' : 1, 'min_helix_length' : 4 }, definition = { 'flagBulge' : dict (type=int,label='Show beta bulges',style='checkbox'), 'min_helix_length' : dict (type=int,label="Min. residues per alpha helix",style= 'spinbox', max=200.0,min=0,step=1), }, help = 'analysis#secstr' ) #MolData.SecStructureParamsManager = services.ParamsManager ( \ # name='SecStr_param', \ # title='SecStructure Parameters', \ # param_order=['NOmaxdist','NOCanglemin','flagBulge'], \ # default = { 'NOmaxdist' : 3.5, \ # 'NOCanglemin' : 90.0, \ # 'flagBulge' : 1 }, \ # gui = {'NOmaxdist' : [float,'Maximum N-O Hbond distance'], \ # 'NOCanglemin' : [float,'Minimum N-O-C Hbond angle'], \ # 'flagBulge' : [int,'Show beta bulges',['TYPE','_logical']] }, \ # help = 'secstr' ) return pm #--------------------------------------------------------------- def createSASAreaPM(name='SASArea_param',copy_from=''): #--------------------------------------------------------------- import services return services.ParamsManager ( name = name, picture_definition = 1, copy_from=copy_from, help = 'analysis#sas', title = 'Solvent accessible surface area', gui=['HOHrad','point_density','brick_margin','exclude_solvent','list_selection_1','list_selection_2','limit_selection'], default = {'HOHrad' : 1.4, 'point_density': 1.0, 'brick_margin': 5.0, 'exclude_solvent': 1, 'exclude_non_polymer': 1, 'list_selection_1': 'polar_atoms', 'list_selection_2': '', 'limit_selection' : 'amino_acid' }, definition = { 'HOHrad' : dict(type=float,label='Water radius',style='spinbox',max=10.0,min=0.0,step=0.5), 'point_density': dict(type=float,label='Point density',style='spinbox',max=2.0,min=0.01,step=0.05), 'brick_margin': dict(type=float,label='Brick margin',style='spinbox',max=20.0,min=0.0,step=1.0), 'exclude_solvent': dict(type=int,label='Exclude water',style='checkbox'), 'exclude_non_polymer': dict(type=int,label='Exclude non-polymer',style='checkbox'), 'list_selection_1' : dict(type=str,label='List total SAS for selected atoms'), 'list_selection_2' : dict(type=str,label='List total SAS for selected atoms'), 'limit_selection' : dict(type=str , label='Apply SAS calculation to', style='combobox', menu=['all non-water','peptide','nucleic acid'],alias=['all','amino_acid','nucleic']) } ) # 'altLoc': 'A' } # 'altLoc' : [text,'For alternate location'] }, #----------------------------------------------------------------- #----------------------------------------------------------------- #----------------------------------------------------------------- class MolDisp(DispObj): #----------------------------------------------------------------- #----------------------------------------------------------------- #----------------------------------------------------------------- # Drawing styles that do not need update of connectivity no_connectivity = ['SPHERES','SURFACE','NUCLEICBASEPAIRS','NUCLEICBASEBLOCKS','LIPIDS','ANISOU'] spline_styles = ['SPLINE','WORM','FATWORM'] custom_spline_style_prefix = 'VARIABLEWORM' connected_styles = ['BONDS','FATBONDS','THINBONDS','BALLSTICK','CYLINDERS','CIRCLES','IMPOSTER_SPHERES'] # 'geometry':['geometry','geometry.geometry.insts.define_bond_menu'] } class_dependents = {} gui_offset = 'display_table' style_menu = ['Bonds','Fat bonds','Thin bonds', 'Ball and stick','Cylinders', \ 'Spheres','Ribbons','Worm','Worms/tubes','Base pair sticks','Nucleic base blocks','Lipid Cartoon','Thermal ellipse','Circles','Perfect spheres','Bloboids','Glycoblocks'] style_commands_icons = {'BONDS':'bonds.svg','FATBONDS':'fatbonds.svg','THINBONDS':'thinbonds.svg','BALLSTICK':'ballandstick.svg','CYLINDERS':'cylinders.svg', \ 'SPHERES':'spheres.svg','SPLINE':'ribbons.svg','WORM':'worms.svg','FATWORM':'wormstubes.svg','NUCLEICBASEPAIRS':'basepairsticks.svg', 'NUCLEICBASEBLOCKS':'baseblocks.svg','LIPIDS':'lipidcartoons.svg','ANISOU':'thermalellipse.svg', 'CIRCLES':'circles.svg','IMPOSTER_SPHERES':'spheres.svg','BLOB_ELLIPSOIDS':'thermalellipse.svg','SUGAR_BLOCKS':'baseblocks.svg'} style_commands = ['BONDS','FATBONDS','THINBONDS','BALLSTICK','CYLINDERS', \ 'SPHERES','SPLINE','WORM','FATWORM','NUCLEICBASEPAIRS', 'NUCLEICBASEBLOCKS','LIPIDS','ANISOU','CIRCLES','IMPOSTER_SPHERES','BLOB_ELLIPSOIDS','SUGAR_BLOCKS'] custom_style_methods = {} style_initialisation = { 'style_mode' : 'BONDS', 'inter_dispobj_bond' : 1 } anisou_style_alias = ['axes','solid','solidaxes'] anisou_style_code = [cprim.SPHEROID_AXES,cprim.SPHEROID_SOLID,cprim.SPHEROID_SOLIDAXES] def __del__(self): pass #print "MolDisp.__del__ -----------------------------------" def toggleBiomolecule(self,nbiomol=-1): if (self.nbiomol==-1 and nbiomol!=-1): self.doBiomolecule = True elif nbiomol == -1 or nbiomol == self.nbiomol: self.doBiomolecule = not self.doBiomolecule self.nbiomol = nbiomol if not self.doBiomolecule: self.nbiomol = -1 if hasattr(self,"graphmod") and hasattr(self.graphmod,"obj") and hasattr(self.graphmod.obj,"SetSymmetryMatrices"): if self.doBiomolecule: self.graphmod.obj.SetSymmetryMatrices([]) self.graphmod.doBiomolecule = self.doBiomolecule self.graphmod.cif_bio_matrices = self.parent.cif_bio_matrices self.graphmod.nbiomol = self.nbiomol self.graphmod.obj.SetDrawSymmetry(1) if hasattr(MAINWINDOW(),"glWidget"): MAINWINDOW().glWidget.SetupSymmetry() import rebuild rebuild.UpdateDisplay() def toggleSymmetryStatus(self): self.doSymmetry = not self.doSymmetry if hasattr(self,"graphmod") and hasattr(self.graphmod,"obj") and hasattr(self.graphmod.obj,"SetSymmetryMatrices"): self.graphmod.doSymmetry = self.doSymmetry if self.doSymmetry: self.graphmod.doCentralSymmetry = self.doCentralSymmetry if hasattr(MAINWINDOW(),"glWidget"): MAINWINDOW().glWidget.SetupSymmetry() import rebuild rebuild.UpdateDisplay() def toggleCentralSymmetryStatus(self): self.doCentralSymmetry = not self.doCentralSymmetry if hasattr(self,"graphmod") and hasattr(self.graphmod,"obj") and hasattr(self.graphmod.obj,"SetSymmetryMatrices"): self.graphmod.doCentralSymmetry = self.doCentralSymmetry if hasattr(MAINWINDOW(),"glWidget"): MAINWINDOW().glWidget.SetupSymmetry() import rebuild rebuild.UpdateDisplay() #------------------------------------------------------------------ def __init__(self,parent,name='',visible=1,master_application=None, \ display_table_visible = 1, selparams={'command':'all'}, colparams={}, styleparams={'style_mode':'BONDS'}, params= {}, \ restore_from_version=0, **keywords): #------------------------------------------------------------------ global gui DispObj.__init__(self,'MolDisp',name, parent,visible=visible, \ master_application=master_application, display_table_visible=display_table_visible, params=params) self.doSymmetry=True self.doCentralSymmetry=True self.doBiomolecule=False self.nbiomol=-1 self.com = [] self.origin = [] # Flag to update display without updating any of the display # attributes - probably set because atom coordinates have # changed import loadPlugins loadPlugins.loadPlugins('initializeStylePlugin') self.reapply_selection=1 self.redraw_picked_labels = 0 self.connectivity_defns = [] self.update_atomRadii = 0 self.do_update_connectivity = 1 self.update_surface = 1 self.built = [] self.pickedAtoms= {} self.pickedAtomsMatrices = {} self.pickedAtomsUserMoveMatrices = {} self.pickedAtomsLabel= {} self.pick_label_graphmod = None self.external_bonds_graphmod = None self.do_redraw = 1 self.do_redraw_external = 1 self.ignore_other_dispobjs = False self.ignore_symmetry = False self.Connectivity = Connectivity() # Set the SelHandle #self.SelHandle = SelHandle(self.parent.name,selparams=selparams,command=selparams.get('command','')) if restore_from_version and restore_from_version[0]==1 and restore_from_version[1]<108: selparams = model_selection.fix_v108(selparams) self.SelHandle = SelHandle(self.parent.name,selparams=selparams) # Ensure global params managers are loaded PM('render_quality').add_dependent(handleRenderParamsManager) if params.has_key('drawing_style'): # Force creating custom drawing stype PM pm = self.getDrawingStylePM(name=params['drawing_style'],custom=1) else: pm = self.getDrawingStylePM() pm.add_dependent(self.handleDrawingStylePM) # Instantiate a a graphics object and assign some parameters import moleculargraphicsmodel self.atomRadii = pygl_coord.DoubleVector(2) for gobj_name in ['graphmod','external_bonds_graphmod']: #for gobj_name in ['graphmod']: gobj = moleculargraphicsmodel.moleculargraphicsmodel( parameters = pm, global_parameters = PM('render_quality')) gobj.setparams(molHnd=self.parent.molHnd, \ Connectivity = self.Connectivity, \ diagnostic_timing = HISTORY().diagnostic['timing']) gobj.setparams(atomRadii=self.atomRadii) setattr(self,gobj_name, gobj) #Interface.__init__(self,contact_MolDisp=params.get('contact_MolDisp')) # Initialise extent - after initilising atom selection self.set_extent() self.masterCrystal = '' # Initialise the style selection parameters for key,value in MolDisp.style_initialisation.items(): setattr(self,key,value) # update style params based on input params self.style = '' self.style_mode = 'BONDS' self.set_style(styleparams=styleparams) self.model_colour=model_colour.model_colour(colparams=colparams,MolData=self.parent,SelHandle=self.SelHandle) self.CMgAppUtils = CMgAppUtils(self.parent.molHnd,self.SelHandle.getSelHnd()) # Setup the label object self.label = None #print "MolDisp label_params",params.get('label_params',{}) self.label = MolLabel(parent=self.name,mol=self.parent.name, \ params = params.get('label_params',{})) if params.has_key('doCentralSymmetry'): self.doCentralSymmetry = params['doCentralSymmetry'] self.graphmod.doCentralSymmetry = self.doCentralSymmetry if params.has_key('nbiomol'): self.nbiomol = params['nbiomol'] self.graphmod.nbiomol = self.nbiomol if params.has_key('doBiomolecule'): self.doBiomolecule = params['doBiomolecule'] self.graphmod.doBiomolecule = self.doBiomolecule self.graphmod.cif_bio_matrices = self.parent.cif_bio_matrices if self.doBiomolecule: self.graphmod.obj.SetDrawSymmetry(1) if params.has_key('doSymmetry'): self.doSymmetry = params['doSymmetry'] self.graphmod.doSymmetry = self.doSymmetry # Anything dependent on creation of a MolDisp? self.update_dependents('create') if self.visible and not MolDisp.no_connectivity.count(self.style): if MolDisp.spline_styles.count(self.style) or self.style.startswith(MolDisp.custom_spline_style_prefix): self.parent.changedSplines.append(self.name) else: self.parent.changedConnected.append(self.name) dispobjs = self.parent.get_dispobj() for dispobj in dispobjs: if hasattr(dispobj,"masterCrystal") and dispobj.masterCrystal!='': self.setMasterCrystal(dispobj.masterCrystal) break if self.doBiomolecule: self.graphmod.obj.SetSymmetryMatrices([]) #-------------------------------------------------------------------- def removeCustomDrawingStyle(self): #-------------------------------------------------------------------- pm = self.getDrawingStylePM() pm.remove_dependent(self.handleDrawingStylePM) if hasattr(self,'drawingStylePM'): del self.drawingStylePM pm = self.getDrawingStylePM() pm.add_dependent(self.handleDrawingStylePM) for gobj_name in ['graphmod','external_bonds_graphmod']: if hasattr(self,gobj_name): getattr(self,gobj_name).setparams(parameters = pm) #-------------------------------------------------------------------- def delete(self,**keywords): #-------------------------------------------------------------------- #print "Deleting MolDisp",self.name if self.visible and not MolDisp.no_connectivity.count(self.style): if MolDisp.spline_styles.count(self.style) or self.style.startswith(MolDisp.custom_spline_style_prefix): self.parent.changedSplines.append(self.name) else: self.parent.changedConnected.append(self.name) if hasattr(self,'label') and self.label: self.label.delete_labels() del self.label DispObj.delete(self) for gobj_name in ['pick_label_graphmod','external_bonds_graphmod']: gobj = getattr(self,gobj_name,None) if gobj: MAINWINDOW().removeGLDisplayObject(gobj) BUILD().deletemod(gobj) if hasattr(self,'Connectivity'): self.Connectivity.Clear() del self.Connectivity if hasattr(self,'CMgAppUtils'): del self.CMgAppUtils if hasattr(self,'SelHandle'): if self.SelHandle.selHnd>=0: mol = data(self.SelHandle.moldata_name) mol.molHnd.DeleteSelection(self.SelHandle.selHnd) self.SelHandle.selHnd = -1 del self.SelHandle if hasattr(self,'drawingStylePM'): self.closeDrawingStylePM(reset=0) else: self.getDrawingStylePM().remove_dependent(self.handleDrawingStylePM) #------------------------------------------------------------------------- def set_visibility ( self,toggle_visibility='',visibility='',**keywords): #------------------------------------------------------------------------- DispObj.set_visibility(self,toggle_visibility=toggle_visibility,visibility=visibility) for gobj_name in ['pick_label_graphmod','external_bonds_graphmod']: gobj = getattr(self,gobj_name,None) if gobj: gobj.obj.visible = self.visible if not MolDisp.no_connectivity.count(self.style): if MolDisp.spline_styles.count(self.style) or self.style.startswith(MolDisp.custom_spline_style_prefix): self.parent.changedSplines.append(self.name) else: self.parent.changedConnected.append(self.name) #------------------------------------------------------------------------ def set_selection(self,command): #------------------------------------------------------------------------ self.SelHandle.setCommand(command) self.reapply_selection=1 #------------------------------------------------------------------------ def set_colour(self,colour): #------------------------------------------------------------------------ self.model_colour.set_colour(one_colour=colour) self.update_dependents('colour') #------------------------------------------------------------------------ def set_reapply_selection(self,mode=1): #------------------------------------------------------------------------ self.reapply_selection = mode def set_redraw_text(self): if self.label: self.label.do_redraw = 1 #------------------------------------------------------------------------ def canBeTransparent(self): #------------------------------------------------------------------------ return 1 #------------------------------------------------------------------------ def isLegendPossible(self): #------------------------------------------------------------------------ return 1 #------------------------------------------------------------------------ def getLegend(self): #------------------------------------------------------------------------ return self.model_colour.getLegend() #------------------------------------------------------------------------ def params ( self , all=1): #------------------------------------------------------------------------ pars = DispObj.params(self,all=all) pars['label_params'] = self.label.params() if not pars['label_params']: del pars['label_params'] if hasattr(self,'doCentralSymmetry'): pars['doCentralSymmetry'] = self.doCentralSymmetry if hasattr(self,'doBiomolecule'): pars['doBiomolecule'] = self.doBiomolecule if hasattr(self,'nbiomol'): pars['nbiomol'] = self.nbiomol if hasattr(self,'doSymmetry'): pars['doSymmetry'] = self.doSymmetry if hasattr(self,'drawingStylePM'): pars['drawing_style'] = self.drawingStylePM.name for item in ['contact_MolDisp']: pars[item] = getattr(self,item,'') return pars def get_colour_label(self): return self.model_colour.colour_label def get_colour_icon(self): return self.model_colour.colour_icon #------------------------------------------------------------------ def selparams(self,all=1): #------------------------------------------------------------------ #print "MolDisp selparams",self.SelHandle.getSaveParams() return self.SelHandle.getSaveParams(all=all) #------------------------------------------------------------------ def colparams(self,all=1): #------------------------------------------------------------------ return self.model_colour.colparams(all=all) #------------------------------------------------------------------ def apply_selection(self): #------------------------------------------------------------------ self.reapply_selection = 0 if ['SURFACE'].count(self.style_mode): self.SelHandle.cleanSelection(close = 0.01) atomtype = self.SelHandle.selparams.get('atomtype') # Set the connectivy rules for bond generation self.connectivity_defns = [] #If is simple catrace then do not need to limit # contact search so there are no selection criteria #print 'apply_selection',self, atomtype, 'command:', self.SelHandle.getCommand() if ['catrace','CA+side'].count(atomtype) or self.SelHandle.getCommand().count('catrace'): trace_selection = 'amino_acid' trace_atom = 'CA' trace_cutoff = self.getDrawingStylePM().get('trace_cutoff') if self.parent.alt_locs: self.connectivity_defns.append([['and',[None,trace_selection],[None,'/*/*/*/'+trace_atom+':'+self.parent.alt_locs[0]+',']],trace_cutoff]) for alt in self.parent.alt_locs[1:]: self.connectivity_defns.append([['and',[None,trace_selection],[None,'/*/*/*/'+trace_atom+':'+alt]],trace_cutoff]) elif atomtype == 'catrace': self.connectivity_defns.append([[],trace_cutoff]) else: self.connectivity_defns.append([[None,'catrace'],trace_cutoff]) elif ['trace'].count(atomtype) or self.SelHandle.getCommand().count('trace'): trace_sel = self.parent.expand_selection_alias('trace') #print 'apply_selection from expand_selection_alias',trace_sel #trace_selection = self.getDrawingStylePM().get('trace_selection') #trace_atom = self.getDrawingStylePM().get('trace_atom') trace_cutoff = self.getDrawingStylePM().get('trace_cutoff') self.connectivity_defns.append([[],trace_cutoff]) self.set_extent() #PICKLABEL().update_label_visibility(self) self.do_recolour = max(1,self.do_recolour) self.do_update_connectivity = 1 self.update_surface = 1 self.model_colour.CMolColour.SetSelHandle(self.SelHandle.getSelHnd()) self.model_colour.do_recolour=2 if self.label: self.label.do_redraw = 2 self.update_atomRadii = 1 if not MolDisp.no_connectivity.count(self.style): if MolDisp.spline_styles.count(self.style) or self.style.startswith(MolDisp.custom_spline_style_prefix): self.parent.changedSplines.append(self.name) else: self.parent.changedConnected.append(self.name) return 1 #if self.dependent: exec self.dependent #self.update_dependents('selection') #------------------------------------------------------------------ def styleparams(self,all=1): #------------------------------------------------------------------ sty = {} if all: for item in MolDisp.style_initialisation.keys(): if hasattr(self,item): sty[item]=getattr(self,item) else: for item in MolDisp.style_initialisation.keys(): if hasattr(self,item) and getattr(self,item) != MolDisp.style_initialisation[item]: sty[item]=getattr(self,item) #print "MolDisp.styleparams",all,sty return sty #----------------------------------------------------------------- def set_style ( self, styleparams={},**kw): #----------------------------------------------------------------- #print "set_style",styleparams,kw styleparams.update(kw) if styleparams: if styleparams.get('inter_dispobj_bond',self.inter_dispobj_bond) != self.inter_dispobj_bond: self.do_redraw=1 if styleparams.get('style_mode',self.style_mode) != self.style_mode: self.do_redraw=1 for item in styleparams.keys(): setattr(self,item,styleparams[item]) # If we are changing between a 'connecting' and a 'non-conecting' # style then need to update_all_bonded_atoms if self.visible and ((not MolDisp.no_connectivity.count(self.style_mode)) or not (MolDisp.no_connectivity.count(self.style)) ): if MolDisp.spline_styles.count(self.style_mode) != MolDisp.spline_styles.count(self.style): self.parent.changedSplines.append(self.name) if MolDisp.no_connectivity.count(self.style_mode) != MolDisp.no_connectivity.count(self.style): self.parent.changedConnected.append(self.name) if ["SPHERES","BALLSTICK",'CIRCLES','IMPOSTER_SPHERES'].count(self.style_mode) and ( self.style_mode != self.style) : self.update_atomRadii = 1 import copy self.style = copy.deepcopy(self.style_mode) self.style_icon = None if self.style_mode in self.style_commands_icons: self.style_icon = self.style_commands_icons[self.style_mode] if os.path.exists(os.path.join(os.environ['CCP4MG'],'qticons','disptab','style',self.style_icon)): self.style_icon = os.path.join(os.environ['CCP4MG'],'qticons','disptab','style',self.style_icon) self.style_label = equivKeyword(self.style,self.style_commands, self.style_menu) #------------------------------------------------------------------------ def centre_on ( self, **keywords): #------------------------------------------------------------------------ VW('mainview').centreModels(dispobj=[self]) #------------------------------------------------------------------------- def clone(self,clone=1,**keywords): #------------------------------------------------------------------------- if self.style == 'SURFACE': visible = 0 else: visible = self.visible selparams = self.selparams() colparams=self.colparams() styleparams=self.styleparams() MolDisp(self.parent.name,visible=visible, selparams=selparams, colparams=colparams, styleparams=styleparams ) return None #----------------------------------------------------------------------- def list_data(self,filename='',overwrite='query',**keywords): #----------------------------------------------------------------------- return self.parent.list_data_file ( list_data=self.name ) #------------------------------------------------------------------------ def getDrawingStylePM(self,name='',custom=0,auto_save=0): #------------------------------------------------------------------------ if custom and not hasattr(self,'drawingStylePM'): if not name: name = 'model_drawing_style'+self.name PM('model_drawing_style').remove_dependent(self.handleDrawingStylePM) self.drawingStylePM = createDrawingStylePM(name=name,copy_from='model_drawing_style') self.drawingStylePM.add_dependent(self.handleDrawingStylePM) for gobj_name in ['graphmod','external_bonds_graphmod']: gobj = getattr(self,gobj_name,None) if gobj: gobj.setparams(parameters=self.drawingStylePM) dt = DISPLAYTABLE() if dt: dt.emit(QtCore.SIGNAL("CustomDrawingStyleChanged")) # Save the status if user opening new PM # (but not if recreating at MolDisp initialisation) if auto_save: HISTORY().autoSave() if hasattr(self,'drawingStylePM'): return self.drawingStylePM else: return PM('model_drawing_style') #------------------------------------------------------------------------ def closeDrawingStylePM(self,reset=1): #------------------------------------------------------------------------ if hasattr(self,'drawingStylePM'): #print "closeDrawingStylePM",self.drawingStylePM.name self.drawingStylePM.remove_dependent(self.handleDrawingStylePM) self.drawingStylePM.delete() del self.drawingStylePM if reset: for gobj_name in ['graphmod','external_bonds_graphmod']: gobj = getattr(self,gobj_name,None) if gobj: gobj.setparams(parameters=PM('model_drawing_style')) PM('model_drawing_style').add_dependent(self.handleDrawingStylePM) #------------------------------------------------------------------------ def handleDrawingStylePM(self,ParamsManager=None,updated={},**keywords): #------------------------------------------------------------------------ # Called when the user hits apply in either the # generic or the custom ParamsManager gui #print "handleDrawingStylePM updated",ParamsManager,updated self.do_redraw = 1 if updated.has_key('ball_radii_scale') and (self.style == "BALLSTICK" or self.style == 'CIRCLES') and \ updated['ball_radii_scale'] > 0.001 and updated['ball_radii_scale'] < 10.0: self.do_redraw = 1 self.update_atomRadii = 1 if updated.has_key('sphere_radii_scale') and (self.style == "SPHERES" or self.style == "IMPOSTER_SPHERES") and \ updated['sphere_radii_scale'] > 0.001 and updated['sphere_radii_scale'] < 10.0: self.do_redraw = 1 self.update_atomRadii = 1 #------------------------------------------------------------------------ def update_connectivity(self): #------------------------------------------------------------------------ if not self.do_update_connectivity: return nSelAtoms,selAtoms = self.SelHandle.getSelIndex() selindexp = pygl_coord.intp() #print "update_connectivity nSelAtoms",self.name,nSelAtoms #start_time = time.clock() self.Connectivity.Clear() if nSelAtoms <= 0: return #self.parent.molHnd.ListBonds(self.SelHandle.getSelHnd(),nSelAtoms,selAtoms) #if self.selection != [None,'catrace']: if self.inter_dispobj_bond: self.Connectivity.AddBonds(self.parent.molHnd,self.SelHandle.getSelHnd(), selAtoms,nSelAtoms,self.parent.all_bonded_atoms,self.parent.all_bonded_atoms_spline) else: self.Connectivity.AddBonds(self.parent.molHnd,self.SelHandle.getSelHnd(), selAtoms,nSelAtoms,0,0) # Loop over definitions for additional connectivities #print self.connectivity_defns for defn in self.connectivity_defns: #print 'MolDisp.update_connectivity',self.name,self.SelHandle.getCommand(),defn if defn[0]: # defn[0] is selection definition to define atoms to apply # contact search # parse the selection and 'and' with the atoms in this # display object status,selHnd1 = self.parent.parse_selection(defn[0]) #print 'update_connectivity',status,selHnd1 if status:break self.parent.molHnd.Select( selHnd1,STYPE_ATOM,self.SelHandle.getSelHnd(),SKEY_AND) selAtoms1 = newPPCAtom() #nSelAtoms1 =self.parent.molHnd.GetSelIndex(selHnd1,selAtoms1) selAtoms1 = mmut.GetAtomSelIndex(self.parent.molHnd,selHnd1,selindexp) nSelAtoms1 = selindexp.value() #print 'update_connectivity nSelAtoms1',nSelAtoms1 self.Connectivity.AddTrace(self.parent.molHnd,selAtoms1,nSelAtoms1, defn[1]) self.parent.molHnd.DeleteSelection(selHnd1) else: # No limiting selection so use all atoms in the display object #print 'update_connectivity nSelAtoms',nSelAtoms self.Connectivity.AddTrace(self.parent.molHnd,selAtoms,nSelAtoms, defn[1]) self.do_update_connectivity = 0 #print 'update_connectivity',self.name,self.Connectivity.GetNumberOfAtoms(),time.clock()-start_time #----------------------------------------------------------------------- def set_do_redraw(self,exit='',max_atoms='',**keywords): #----------------------------------------------------------------------- self.do_redraw = 1 #----------------------------------------------------------------------- def unthreadedDraw(self): #----------------------------------------------------------------------- self.draw_text() self.draw_pick_text() #print 'MolDisp.unthreadedDraw', self.do_rebuildGL #----------------------------------------------------------------------- def draw_text(self): #----------------------------------------------------------------------- #print 'MolDisp.unthreaded_draw',self.do_redraw,self.label.do_redraw rebuild = 0 if self.reapply_selection>0: selection_changed=self.apply_selection() if self.label and self.label.do_redraw: # Redo the picked labels if they have been trashed by the MolLabel.draw if not self.label_graphmod: import graphicsmodel self.label_graphmod = graphicsmodel.graphicsmodel() BUILD().append(self.label_graphmod) rebuild = self.label.draw() if rebuild: self.do_rebuildGL.append('label_graphmod') return rebuild #----------------------------------------------------------------------- def clearPickedAtoms(self): #----------------------------------------------------------------------- import cprim for uid,label_ob in self.pickedAtomsLabel.items(): cprim.DeleteTextLabel(self.pick_label_graphmod.obj,label_ob.GetID()) self.pickedAtomsLabel = {} self.pickedAtoms = {} self.pickedAtomsMatrices = {} self.pickedAtomsUserMoveMatrices = {} #----------------------------------------------------------------------- def draw_pick_text(self): #----------------------------------------------------------------------- import pygl_coord,cprim,TextLabel if not self.redraw_picked_labels: return 0 for uid,label_ob in self.pickedAtomsLabel.items(): cprim.DeleteTextLabel(self.pick_label_graphmod.obj,label_ob.GetID()) self.pickedAtomsLabel = {} font = FONTMANAGER().getFont('pick_atom_label') if not self.pick_label_graphmod: import graphicsmodel self.pick_label_graphmod = graphicsmodel.graphicsmodel() BUILD().append(self.pick_label_graphmod) for uid,atm_ptr in self.pickedAtoms.items(): pos = pygl_coord.Cartesian(atm_ptr.x,atm_ptr.y,atm_ptr.z) if self.pickedAtomsMatrices.has_key(uid) and self.pickedAtomsMatrices[uid]: pos = self.pickedAtomsMatrices[uid]*pos if self.pickedAtomsUserMoveMatrices.has_key(uid) and self.pickedAtomsUserMoveMatrices[uid]: pos = self.pickedAtomsUserMoveMatrices[uid]*pos text_label = PICKLABEL().getAtomLabel(atm_ptr ) #print "MolDisp.draw_pick_text text_label",text_label #label_ob = cprim.Text(pygl_coord.Cartesian(atm_ptr.x,atm_ptr.y,atm_ptr.z),text_label, # pygl_coord.Cartesian(atm_ptr.x,atm_ptr.y,atm_ptr.z)) label_ob = TextLabel.CreateTextLabel(text_label, pos, pos,font) glWidget = GLWIDGETS()[0] if glWidget and hasattr(glWidget,"getBackground") and callable(glWidget.getBackground): bgcol = glWidget.getBackground() bright_y = bgcol[0]*0.299 + bgcol[1]*0.587 + bgcol[2]*0.114; if bright_y <0.5: label_ob.SetColour(1,1,1,1) else: label_ob.SetColour(0,0,0,0) #print 'MolDisp.drawPickedLabels',label_ob,self.graphmod.obj self.pickedAtomsLabel[uid] = label_ob self.pick_label_graphmod.obj.add_text_primitive(label_ob) self.redraw_picked_labels = 0 #print 'MolDisp.draw_pick_text', self.pickedAtomsLabel self.do_rebuildGL.append('pick_label_graphmod') return 1 #------------------------------------------------------------------------ def draw (self): #------------------------------------------------------------------------ ''' Called at end of each cycle of a command loop Redraw the graphmod if necessary ''' start_time = time.time() # Get the build module to build this object #print "MolDisp.draw",self.name,self.reapply_selection,self.do_redraw selection_changed = 0 colour_changed=0 pm = self.getDrawingStylePM() if self.reapply_selection>0: selection_changed=self.apply_selection() if selection_changed: self.do_redraw=1 #print 'MolDisp.draw',self.name,self.do_redraw,self.parent.do_update_all_bonded_atoms,self.parent.changedSplines,self.parent.changedConnected if not self.ignore_other_dispobjs and (self.parent.do_update_all_bonded_atoms or self.parent.changedSplines or self.parent.changedConnected): self.parent.update_all_bonded_atoms() #print "from update_all_bonded_atoms" if self.do_update_connectivity: self.update_connectivity() if self.model_colour.do_recolour: colour_changed = self.model_colour.apply_colour() #print "MolDisp.draw colour_changed",colour_changed #print self.model_colour.colour_mode self.do_redraw=1 for gobj_name in ['graphmod']: gobj = getattr(self,gobj_name,None) if gobj: if hasattr(gobj,"parameters") and hasattr(gobj.parameters,"CParamsManager") and hasattr(gobj.parameters.CParamsManager,"SetInt") and hasattr(self,"model_colour") and hasattr(self.model_colour,"colour_mode"): if self.model_colour.colour_mode == "restype": gobj.parameters.CParamsManager.SetInt("two_glycoblock_colour",1) else: gobj.parameters.CParamsManager.SetInt("two_glycoblock_colour",0) if ['SPHERES','BALLSTICK','CIRCLES','IMPOSTER_SPHERES'].count(self.style_mode): if self.update_atomRadii and self.SelHandle.getSelHnd()>=0: if self.atomRadii: del self.atomRadii if self.style_mode == "SPHERES" or self.style_mode == "IMPOSTER_SPHERES": scale = pm.get('sphere_radii_scale') elif self.style == "BALLSTICK" or self.style == 'CIRCLES': scale = pm.get('ball_radii_scale') self.atomRadii=self.parent.molHnd.GetAtomRadii(self.SelHandle.getSelHnd(),VDWRADIUS,scale) for gobj_name in ['graphmod','external_bonds_graphmod']: gobj = getattr(self,gobj_name,None) if gobj: gobj.setparams(atomRadii=self.atomRadii) self.update_atomRadii=0 if ['ANISOU'].count(self.style_mode): if self.atomRadii: del self.atomRadii style_code = MolDisp.anisou_style_code[MolDisp.anisou_style_alias.index(pm.get('anisou_style'))] scale=1.0 self.atomRadii=self.parent.molHnd.GetAtomRadii(self.SelHandle.getSelHnd(),VDWRADIUS,scale) for gobj_name in ['graphmod','external_bonds_graphmod']: gobj = getattr(self,gobj_name,None) if gobj: gobj.setparams(anisou_style=style_code,anisou_scale=pm.get('anisou_scale')) gobj.setparams(atomRadii=self.atomRadii) if self.do_redraw or self.do_redraw_external: #print "MolDisp.draw",self.name,self.do_redraw,self.do_redraw_external # Update graphmod parameters nSelAtoms,selAtoms = self.SelHandle.getSelIndex(always=1) #print "MolDisp.draw nSelAtoms",nSelAtoms,selAtoms selHnd = self.SelHandle.getSelHnd(always=1) if self.model_colour.stick_colour == 'ATOM': stick_colour_code = -1 else: stick_colour_code = MGCOLOUR().index(self.model_colour.stick_colour) import cprim do_redraw = 0 for gobj_name,do_redraw_name,external_bonds_mode in [['graphmod','do_redraw',cprim.DRAW_INTERNAL_BONDS], ['external_bonds_graphmod','do_redraw_external',cprim.DRAW_EXTERNAL_BONDS]]: do_redraw = max(do_redraw,getattr(self,do_redraw_name,0)) for gobj_name,do_redraw_name,external_bonds_mode in [['graphmod','do_redraw',cprim.DRAW_INTERNAL_BONDS], ['external_bonds_graphmod','do_redraw_external',cprim.DRAW_EXTERNAL_BONDS]]: #do_redraw = getattr(self,do_redraw_name,0) gobj = getattr(self,gobj_name,None) if gobj: if do_redraw: if hasattr(self,"parent") and hasattr(self.parent,"sugar_stack_inter"): gobj.setparams(sugar_stack_inter=self.parent.sugar_stack_inter) gobj.setparams(stick_colour=stick_colour_code) gobj.setparams(selHnd=selHnd, \ selAtoms = selAtoms, \ nSelAtoms = nSelAtoms, \ com = self.com, \ origin = self.origin, \ style = self.style, \ visible = self.visible, \ update_surface = self.update_surface, atomColourVector = self.model_colour.atomColourVector, \ ifColourContinuous = self.model_colour.ifColourContinuous, external_bonds_mode= external_bonds_mode, side_to_ribbon=self.parent.spline_selHnd, side_to_worm=self.parent.worm_selHnd, splineinfo_ribbon=self.parent.splineinfo_ribbon, splineinfo_worm=self.parent.splineinfo_worm ) if not self.built.count(gobj_name): BUILD().append(gobj) gobj.obj.SetAlpha(self.opacity) self.built.append(gobj_name) if self.doBiomolecule: self.graphmod.obj.SetSymmetryMatrices([]) if not self.ignore_symmetry: for gl in MAINWINDOW().glWidgets: gobj.SetupSymmetry(gl.rpos,gl.extents()) else: #print "before graphmod.rebuild",self.name, time.time()-start_time #gobj.diagnostic_timing = 1 gobj.rebuild() #print "after graphmod.rebuild",self.name, time.time()-start_time gobj.obj.SetAlpha(self.opacity) #print "after SetAlpha",self.name, time.time()-start_time if not self.ignore_symmetry: for gl in MAINWINDOW().glWidgets: gobj.SetupSymmetry(gl.rpos,gl.extents()) #print "after SetupSymmetry",self.name, time.time()-start_time # This forces recalculation of connections of side-chains, SS bridges, etc. to worm. self.set_visibility(toggle_visibility=1) self.set_visibility(toggle_visibility=1) self.do_rebuildGL.append(gobj_name) if self.do_update_opacity: for gobj_name in ['graphmod','external_bonds_graphmod']: gobj = getattr(self,gobj_name,None) if gobj: gobj.obj.SetAlpha(self.opacity) if not self.do_rebuildGL.count(gobj_name): self.do_rebuildGL.append(gobj_name) self.do_redraw = 0 self.do_redraw_external = 0 self.do_update_opacity = 0 #print 'MolDisp.draw',self.parent.name,self,do_updatedisplay return 0 #----------------------------------------------------------------------- def set_extent(self): #----------------------------------------------------------------------- self.extent = [0.0,0.0,0.0,0.0,0.0,0.0] if self.SelHandle.getNofAtoms() > 0: ext = self.parent.molHnd.Extent(self.SelHandle.getSelHnd()) if len(ext)>0: self.extent = [] for i in range(0,6): self.extent.append (ext[i]) ext = () del ext #print "extent",sel.extent self.origin = [ \ (self.extent[3] + self.extent[0])/2.0, (self.extent[4] + self.extent[1])/2.0, (self.extent[5] + self.extent[2])/2.0 ] #print "sel.origin",sel.origin self.com = [0.0,0.0,0.0] #---------------------------------------------------------------- def set_graphmod_visibility(self): #---------------------------------------------------------------- vis = DispObj.set_graphmod_visibility(self) if self.pick_label_graphmod: self.pick_label_graphmod.obj.visible = vis if self.external_bonds_graphmod: self.external_bonds_graphmod.obj.visible = vis return vis #---------------------------------------------------------------- def handle_moving_data(self,attribute='',master='',**keywords): #---------------------------------------------------------------- #print 'MolDisp.handle_moving_data',self if self.style == 'SURFACE': if attribute == 'transform': #self.set_visibility(visibility=0) self.reapply_selection=1 elif attribute == 'reconfigure': self.reapply_selection=1 else: self.do_redraw = 1 #----------------------------------------------------------------- def update_data_status(self,shadowdisp): #----------------------------------------------------------------- import utils rv = 0 edited_list = [] diffs = utils.dict_diffs(self.selparams(),shadowdisp.selparams)[1] #print "MolDisp.update_data_status selparams diffs",diffs if diffs: self.SelHandle.setSelParams(shadowdisp.selparams) self.reapply_selection = 1 rv = 1 diffs = utils.dict_diffs(self.colparams(),shadowdisp.colparams)[1] if diffs: self.model_colour.set_colour(colparams=diffs) rv = 1 diffs = utils.dict_diffs(self.styleparams(),shadowdisp.styleparams)[1] if diffs: self.set_style(styleparams=diffs) self.do_redraw = 1 rv = 1 rv0,diffs,undiffs = utils.dict_diffs(self.params(),shadowdisp.params) #print "MolDisp update_data_status diffs",diffs if diffs: if diffs.has_key('label_params'): self.label.update_data_status(diffs['label_params']) rv = 1 if diffs.has_key('drawing_style'): #Add a drawing style PM pm = self.getDrawingStylePM(name=diffs['drawing_style'],custom=1) #print "diffs drawing_style",pm.name,pm.params pm.add_dependent(self.handleDrawingStylePM) for gobj_name in ['graphmod','external_bonds_graphmod']: gobj = getattr(self,gobj_name,None) if gobj: gobj.setparams(parameters=pm) self.do_redraw = 1 HISTORY().update_gui.append(['add_PM',diffs['drawing_style']]) rv = 1 if undiffs.has_key('drawing_style'): #print "undiffs drawing_style" #Remove a drawing style PM HISTORY().update_gui.append(['delete_PM',undiffs['drawing_style']]) self.closeDrawingStylePM() self.do_redraw = 1 rv = 1 if rv: self.update_gui.append(['update']) rv = max(rv, DispObj.update_data_status0(self,shadowdisp)) return rv def addPickedAtom(self,uid,atm_ptr,matrix=None): x,y,z = atm_ptr.x,atm_ptr.y,atm_ptr.z for uid1,pa in self.pickedAtoms.items(): x1,y1,xz = pa.x,pa.y,pa.z if abs(x-x1)<1e-5 and abs(y-y1)<1e-5 and abs(y-y1)<1e-5: print "Already have a pick label here" self.removePickedAtom(uid1) self.redraw_picked_labels = 1 return uid1 self.pickedAtoms[uid] = atm_ptr self.pickedAtomsMatrices[uid] = matrix self.redraw_picked_labels = 1 return 0 #print 'MolDisp.addPickedAtom', self.pickedAtoms, self def removePickedAtom(self,uid): import cprim if self.pickedAtomsLabel.has_key(uid): cprim.DeleteTextLabel(self.pick_label_graphmod.obj,self.pickedAtomsLabel[uid].GetID()) del self.pickedAtomsLabel[uid] if self.pickedAtomsMatrices.has_key(uid): del self.pickedAtomsMatrices[uid] if self.pickedAtomsUserMoveMatrices.has_key(uid): del self.pickedAtomsUserMoveMatrices[uid] if self.pickedAtoms.has_key(uid): del self.pickedAtoms[uid] self.redraw_picked_labels = 1 #cprim.DeleteTextLabel(obj,label_ob.GetID()) #************************************************************************* # Beware the following are functions #************************************************************************* def convertSecstrCode(inp=''): import types if isinstance(inp,types.StringType): if MolData.secstr_menu.count(inp): return MolData.secstr_enum[MolData.secstr_menu.index(inp)] else: return -2 else: if MolData.secstr_enum.count(inp): return MolData.secstr_menu[MolData.secstr_enum.index(inp)] else: return ' ' #--------------------------------------------------------------------------------- def createDrawingStylePM(name='',copy_from=''): #--------------------------------------------------------------------------------- import services import re title='Model drawing style '+re.sub('model_drawing_style','',name) pm = services.ParamsManager ( name=name, #custom_gui = graphics_draw_gui, picture_definition = 1, copy_from=copy_from, help="drawing_styles", c_access= 1, title=title, gui=['bond_width','fat_bond_width','thin_bond_width', 'dashed_bonds','dashed_bond_length','show_multiple_bonds','deloc_ring', 'cylinder_width', 'ballstick_stick','ball_radii_scale', 'sphere_radii_scale','nucleic_stick_width','base_block_thickness', 'alpha_helix_width','ribbon_width','arrow_width','worm_width','helix_tube_diameter', 'ribbon_style','helix_style', 'flatten_loop','loop_frac','flatten_beta','two_colour_ribbon','grey_ribbon_edge', 'anisou_style','anisou_scale','anisou_scale_byvdw','trace_cutoff', 'glycoblock_stick_colour','glycoblock_thickness','glycoblock_scale','glycoblock_draw_cov_protein_interactions','glycoblock_draw_protein_interactions', 'glycoblock_interaction_style', 'glycoblock_interaction_colour', 'glycoblock_interaction_cylinder_radius','glycoblock_interaction_line_width', 'glycoblock_interaction_dash_length','glycoblock_label_protein_interactions'], default = { 'bond_width' : 2, 'fat_bond_width' : 4, 'thin_bond_width' : 1, 'cylinder_width' : 0.2, 'nucleic_stick_width' : 0.4, 'ballstick_stick' : 0.1, 'ribbon_width' : 2.5, 'alpha_helix_width' : 1.5, 'helix_tube_diameter' : 1.5, 'arrow_width' : 2.2, 'arrow_length' : 2.2, 'worm_width' : 0.2, 'ribbon_style' : 0, 'two_colour_ribbon' : 0, 'grey_ribbon_edge' : 0, 'helix_style' : 0, 'flatten_loop' : 0, 'loop_frac' : 1, 'flatten_beta' : 1, 'deloc_ring' : 0, 'show_multiple_bonds' : 0, 'anisou_scale_byvdw' : 0, 'sphere_radii_scale' : 1.0, 'ball_radii_scale' : 0.2, 'spline_beta_flat' : 1, 'dashed_bonds' : 0, 'dashed_bond_length' : 0.3, 'pyramid_size' : 0.1, 'anisou_style' : 'solidaxes', #'anisou_style' : 0, 'anisou_scale' : 1.0, #'trace_selection' : 'amino_acid', #'trace_atom' : 'CA', 'trace_cutoff' : 4.8, 'glycoblock_stick_colour' : 'black' , 'glycoblock_interaction_colour' : 'black', 'glycoblock_interaction_cylinder_radius' : 0.1, 'glycoblock_thickness' : 0.35, 'glycoblock_scale' : 1.3, 'glycoblock_interaction_line_width' : 2, 'glycoblock_interaction_dash_length' : 0.36, 'glycoblock_draw_protein_interactions' : 0, 'glycoblock_draw_cov_protein_interactions' : 1, 'glycoblock_label_protein_interactions' : 0, 'glycoblock_interaction_style' : 'Dashed cylinder', 'base_block_thickness' : 0.2 }, definition = {'bond_width' : dict(type=int,label='Bond width',style='spinbox', min=1,max=10), 'fat_bond_width' : dict(type=int,label='Fat bond width',style='spinbox', min=1,max=10), 'thin_bond_width' : dict(type=int,label='Thin bond width',style='spinbox', min=1,max=10), 'dashed_bonds' : dict(type=int,label='Dashed bonds',style='checkbox'), 'dashed_bond_length' : dict(type=float,label='Dash length for dashed bonds', style='spinbox',max=1.0,min=0.0,step=0.02), 'sphere_radii_scale' : dict(type=float,label='Sphere radius = VDW radii x', style='spinbox',max=5.0,min=0.0,step=0.02), 'ball_radii_scale' : dict(type=float,label='Ball radius = VDW radii x', style='spinbox',max=5.0,min=0.0,step=0.02), 'ballstick_stick' : dict(type=float,label='Ball cylinder thickness', style='spinbox',max=5.0,min=0.0,step=0.02), 'worm_width': [float,''], 'ribbon_style': dict(type=int,label='Nucleic acid/strand ribbon style', style='combobox',menu=['Oval','Flat','Flat/round'],alias=[0,1,2]), 'helix_style': dict(type=int,label='Helix ribbon style',style='combobox', menu=['Oval','Flat','Flat/Round','Fancy'],alias=[0,1,2,3]), 'two_colour_ribbon': dict(type=int,label='Helix colouring',style='combobox', menu=['Normal','Inside grey'],alias=[0,1]), 'grey_ribbon_edge': dict(type=int,label='Ribbon colouring',style='combobox', menu=['Normal','Edges grey'],alias=[0,1]), 'cylinder_width': dict(type=float,label='Cylinder thickness (Angstrom)', style='spinbox',max=5.0,min=0.0,step=0.02), 'nucleic_stick_width': dict(type=float,label='Nucleic base stick thickness (A)', style='spinbox',max=5.0,min=0.0,step=0.02), 'alpha_helix_width': dict(type=float,label='Protein ribbon width', style='spinbox',max=10.0,min=0.0,step=0.02), 'arrow_width': dict(type=float,label='Beta strand arrrow width', style='spinbox',max=10.0,min=0.0,step=0.02), 'ribbon_width': dict(type=float,label='Nucleic acid ribbon width', style='spinbox',max=10.0,min=0.0,step=0.02), 'flatten_loop' : dict(type=bool,label='Shorten loops',style='checkbox'), 'loop_frac': dict(type=float,label='Degree of loop shortening (0-1)', style='spinbox',max=1.0,min=0.0,step=0.02), 'flatten_beta' : dict(type=bool,label='Smooth beta-sheets',style='checkbox'), 'show_multiple_bonds' : dict(type=bool,label='Show multiple-bonds',style='checkbox'), 'deloc_ring' : dict(type=bool,label='Draw deloc. circle in aromatic rings',style='checkbox'), 'worm_width': dict(type=float,label='Worm width', style='spinbox',max=10.0,min=0.0,step=0.02), 'helix_tube_diameter': dict(type=float,label='Helix tube diameter', style='spinbox',max=10.0,min=0.0,step=0.2), 'spline_beta_flat': dict(type=int), 'pyramid_size' : dict(type=float,label='Pyramid size', style='spinbox',max=10.0,min=0.0,step=0.02), 'anisou_style' : dict (type=str,label='Thermal ellipse style',style='combobox', menu = ['Axes','Solid','Solid&Axes'],alias = ['axes','solid','solidaxes']), 'anisou_scale' : dict (type=float,label='Thermal ellipse scale',style='spinbox', max=10.0,min=0.0,step=0.05), 'anisou_scale_byvdw' : dict(type=bool,label='Scale ellipses by VDW radii',style='checkbox'), #'trace_selection' : dict ( type=str, label = "'CA' trace selection"), #'trace_atom' : dict ( type=str, label = "'CA' trace atom"), 'trace_cutoff' : dict (type=float,label="'CA' trace cutoff distance",style= 'spinbox', max=20.0,min=0.0,step=1.0), 'base_block_thickness': dict(type=float,label='Base block thickness', style='spinbox',max=10.0,min=0.0,step=0.05), 'glycoblock_stick_colour' : dict(type=str,label='Glycoblock stick colour',style='colourcombo'), 'glycoblock_interaction_colour' : dict(type=str,label='Glycoblock interaction colour',style='colourcombo'), 'glycoblock_interaction_cylinder_radius': dict(type=float,label='Glycoblock cylinder radius', style='spinbox',max=10.0,min=0.0,step=0.05), 'glycoblock_thickness': dict(type=float,label='Glycoblock thickness', style='spinbox',max=10.0,min=0.0,step=0.02), 'glycoblock_scale': dict(type=float,label='Glycoblock scale', style='spinbox',max=2.0,min=0.0,step=0.01), 'glycoblock_interaction_line_width': dict(type=int,label='Glycoblock H-Bond line width', style='spinbox',max=10,min=1,step=1), 'glycoblock_interaction_dash_length': dict(type=float,label='Glycoblock H-Bond dash length', style='spinbox',max=2.0,min=0.0,step=0.01), 'glycoblock_draw_protein_interactions' : dict(type=bool,label='Draw glyco-protein H-Bond/stack interaction ',style='checkbox'), 'glycoblock_draw_cov_protein_interactions' : dict(type=bool,label='Draw glyco-protein covalent cartoon',style='checkbox'), 'glycoblock_label_protein_interactions' : dict(type=bool,label='Glyco-protein distance labels',style='checkbox'), 'glycoblock_interaction_style' : dict(type=str, label='Glycoblock H-Bond style', style='combobox',menu=['Dashed line','Dashed cylinder']), } ) return pm #--------------------------------------------------------------------------------- def createRenderParamsManager(): #--------------------------------------------------------------------------------- import services pm = services.ParamsManager ( name="render_quality", picture_definition = 1, help="drawing_styles#render_quality", title='Drawing quality', c_access= 1, gui=['solid_quality', 'smooth_line', 'use_vbo', 'force_use_va'], default = { 'solid_quality' : 1, 'smooth_line' : 1, 'use_vbo' : 1, 'force_use_va':0 }, definition = { 'solid_quality' : dict(type=int,label='Solid objects drawing quality', style='combobox',menu=['Fast','Smooth','Deluxe'],alias=[0,1,2]), 'smooth_line' : dict(type=bool, label='Anti-alias lines', style='checkbox' ), 'use_vbo' : dict(type=bool, label='Use vertex buffer objects', style='checkbox' ), 'force_use_va' : dict(type=bool, label='Force Vertex Arrays on Win32/Intel', style='checkbox' ) }) return pm def handleRenderParamsManager(updated={},**keywords): # Called on changing RenderParamsManager param - redraw all MolDisp for disp in get_dispobj(object_type='MolDisp',mode='all'): disp.do_redraw = 1 return 0 #----------------------------------------------------------------------- def strip_html_from_PDB(filename=''): #----------------------------------------------------------------------- ''' Strip html tags from PDB that might have come from doing 'Save to' in web browser viewing EBI ''' import re import string import os #print "Stripping html tags from filename",filename #print "Copying original file to",filename+'.html' os.rename(filename,filename+'.html') try: f = open(filename+'.html','r') except: return [1,'Error opeing file: '+filename+'.html'] l = f.read() f.close() # Extract everything between
 and (.+)
(.+)',l,re.DOTALL) if not t: return [2,'Error attempting to find
 tags in file:\n',filename]

  l = t.groups()[1]

  # Separate out the ATOM records to speed up searching
  n = string.find(l,'\nATOM')
  #print n
  if n>0:
    l1 =  l[0:n]
  else:
    l1 = l
    
  #Remove the 
  t =  re.search('(.+)(.+)',l1,re.DOTALL)
  while t:
    #print "removing "
    l1 = t.groups()[0] + t.groups()[1]
    t =  re.search('(.+)(.+)',l1,re.DOTALL)

  # Remove the 
  t = re.search("(.+)(.+)",l1,re.DOTALL)
  while t:
    #print 'removing '
    l1 = t.groups()[0] + t.groups()[2]
    t = re.search("(.+)(.+)",l1,re.DOTALL)

  try:
    f = open(filename,'w')
    if n>0:
      f.write(l1+l[n:])
    else:
      f.write(l1)
    f.close
  except:
    return [3,'Error attempting to write cleaned up file:\n',filename]

  return [0,'']

def list_user_colour_rules():
  for obj in MolData.insts:
    print "**",obj.name
    if hasattr(obj.objinsts[0],'colour_rules'):
      print obj.objinsts[0].colour_rules[1][0]
    #print obj.objinsts[0].user_colour_objects