#!/usr/bin/python import os,sys from process import process import common par=common.parameter class refatompick(process): name="iterative substructure improvement and phasing" short_name="substructure improvement" supported_procs=["ref", "phas", "atomsfrommap"] supported_params = {} supported_params['target'] = par( desc='Experiment/refinement target', typ=str, cap=True, share=True ) supported_params['refcyc'] = par( desc='Number of refinement cycles in each iteration', typ=int ) supported_params['num_iter'] = par( desc='Number of refinement+picking iterations', typ=int ) supported_params['rms_threshold'] = par( desc='RMS threshold for atom picking from map (negative disables picking)', typ=float, share=True ) supported_params['occ_cut'] = par( desc='Occupancy threshold for atom deletion (relative to largest occ; negative to disable)', typ=float ) supported_params['skip_init_ref'] = par( desc='Skip the initial refinement', typ=bool ) supported_params['skip_last_pick'] = par( desc='Skip atom picking in the last iteration', typ=bool ) supported_params['skip_last_occ_cut'] = par( desc='Skip atom deletion in the last iteration', typ=bool ) supported_params['skip_init_occ_cut'] = par( desc='Skip atom deletion in the initial model', typ=bool ) supported_params['max_new_atoms'] = common.parameter( desc='Maximal number of atoms added in one iteration', typ=(int,bool), share=True ) supported_params['bfactor'] = par( desc='Set B factor of the new atoms to this value', typ=(float,bool), share=True ) supported_params['res_cut'] = par( desc='Use (automatic if True) resolution cutoff in refinement', typ=(float,bool), share=True ) supported_params['res_cut_cyc'] = par( desc='Number of refinement cycles with the resolution cutoff (default all)', typ=int, share=True ) def Init(self): self.lastcut=None def TreatInOutPar(self, set_all_par=False): # input self.ph = self.GetProcess('phas') if not self.ph: self.ph = self.GetProcess('ref') if not self.ph: if self.inp.Get('model',typ=('partial','partial+substr'),filetype='pdb'): self.ph = self.AddProcess('ref') else: self.ph = self.AddProcess('phas') if not self.ph.GetProg(): self.ph.AddProg('refmac') self.ph.TreatInOutPar() self.afm = self.GetOrAddProcess('atomsfrommap') self.afm.TreatInOutPar() # parameters if not self.IsParam('num_iter'): self.SetParam('num_iter', 3) if self.GetParam('rms_threshold') is None: self.SetParam('rms_threshold', 4.75) if self.GetParam('skip_last_pick') is None: self.SetParam('skip_last_pick') if self.GetParam('occ_cut') is None: if self.ph.nick=='phas': self.SetParam('occ_cut',0.3) if self.inp.Get('model',has_atomtypes=True) and self.inp.Get('model',has_atomtypes=True).GetAtomType() in ('I'): self.SetParam('occ_cut',0.25) else: self.SetParam('occ_cut',0.15) if self.GetVirtPar('refcyc') is None and self.ph.nick=='ref': self.SetVirtPar('refcyc', 10) if self.ph.GetParam('low_res_par'): self.SetVirtPar('refcyc', 20) #if self.GetVirtPar('refcyc') is None and self.ph.nick=='phas': # self.SetVirtPar('refcyc', 25) if self.IsVirtPar('refcyc') and not self.ph.IsVirtPar('cycles'): self.ph.SetParam('cycles', self.GetVirtPar('refcyc')) # if not self.IsParam('res_cut') and self.GetParam('target')=='SAD' and self.ph.nick=='phas' and \ # self.inp.Get('model',has_atomtypes=True) and self.inp.Get('model',has_atomtypes=True).GetAtomType() in ('S','CA','CR','MN','FE','CO','NI','CU','ZN','SE','BR'): #self.inp.Get('model',has_atomtypes=True) and self.inp.Get('model',has_atomtypes=True).GetAtomType() in ('S','CA'): # self.SetParam('res_cut') process.TreatInOutPar(self,set_all_par) def GetOcc(self,pdb): pdbcur=self.GetOrAddProg('pdbcur') pdbcur.inp.Set(pdb) with open(pdb.GetFileName('pdb')) as f: occ = pdbcur.GetStatGrep('occup',from_str=f.read()) return occ,pdbcur def CutOcc(self,occ,pdbcur,init=False): maxocc = max(occ) if occ else 1. pdbcur.SetKey('cutocc', self.GetParam('occ_cut')*maxocc, keep_previous=False) pdbcur.Run() message=pdbcur.GetStat('atoms_deleted_occ',accept_none=True) if message: self.Info(message) if self.rv_report is not None: self.rv_report.Text(' '+message if not init else message) self.inp.Add(pdbcur.out.Get('model')) return message def RunBody(self,*args,**kwargs): if self.GetParam('res_cut') and not self.ph.GetProg(supported=True).IsKey('reso'): if self.GetParam('res_cut') is True: substrdet=self.AddProcess('substrdet', propagate_out=False) cutoff = substrdet.EstimateCutOff() self.processes.remove(substrdet) else: cutoff = float( self.GetParam('res_cut') ) if cutoff: self.ph.GetProg(supported=True).SetKey('reso', cutoff) model_type = 'substr' if self.ph.nick=='phas' else 'partial+substr' if self.ph.nick=='phas' and not self.GetParam('skip_init_occ_cut'): occ,pdbcur=self.GetOcc( self.inp.Get('model',typ=model_type,filetype='pdb') ) self.CutOcc( occ,pdbcur, init=True ) refprob=0 for i in range(self.GetParam('num_iter')): self.LGInfo('\n$TEXT: Iteration {0}: $$ Atom picking result $$'.format(i+1)) self.lastcut=None if self.rv_report is not None: self.rv_report.Text("Iteration {0}.".format(i+1)) self.afm.rv_report = self.rv_report #if self.GetParam('res_cut') and i==self.GetParam('num_iter')-1: # self.ph.GetProg().SetKey('reso',False,keep_previous=False) if i>0 or not self.GetParam('skip_init_ref'): self.ph.GetProg().runname=self.ph.GetProg().name+'_cyc'+str(i) self.ph.GetProg().outfilename['pdb']=self.ph.GetProg().name+'_cyc'+str(i)+'.pdb' if self.GetParam('res_cut_cyc')==i: self.ph.GetProg().SetKey('reso',False,keep_previous=False) if self.ph.nick=='ref' and not self.ph.inp.Get('model',('partial+substr','substr'),filetype='pdb') and self.ph.inp.Get('model','partial',filetype='pdb'): ph_backup=self.ph.GetProg().BackupAnyPars() self.ph.GetProg().SetKey('anom','mapo') self.ph.GetProg().SetKey('ncyc',0) self.ph.SetParam('no_substr',True) self.ph.Run() self.ph.GetProg().RestoreAnyPars(ph_backup) self.ph.SetParam('no_substr',False) self.afm.inp.AddCopy(self.out.Get('model',typ='partial')) else: self.ph.Run() if self.GetParam('occ_cut')>=0.0 and (i=50: cyc=self.ph.GetParam('cycles') problemcyc = 0 if refprob else 1 self.ph.SetParam('cycles',problemcyc) self.ph.Run() self.ph.SetParam('cycles',cyc) occ,pdbcur=self.GetOcc( self.out.Get('model',typ=model_type,filetype='pdb') ) self.CutOcc( occ,pdbcur ) if refprob: self.Info('Substructure improvement not likely to improve the substructure. Stopping.') break refprob+=1 self.lastcut=self.CutOcc( occ,pdbcur ) self.afm.inp.AddCopy(self.out.Get('model',typ=model_type)) self.afm.inp.Set(self.ph.out.GetAll('mapcoef')) if self.GetParam('rms_threshold')>0.0 and (i