"""
CTaskCrank2.py
Copyright (C) 2011 University of York, Leiden University
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.
"""
import os
import types
import functools
import traceback
from qtgui import CCP4TaskWidget
from qtgui import CCP4Widgets
from core import CCP4Utils
from . import crank2_basepipe
from PyQt4 import QtGui, QtCore
class CTaskCrank2(CCP4TaskWidget.CTaskWidget):
TASKNAME = 'crank2'
TASKVERSION = 0.02
TASKMODULE='expt_phasing'
TASKTITLE='Automated structure solution - CRANK2 phasing and building'
SHORTTASKTITLE='CRANK2'
DESCRIPTION='CRANK2 experimental phasing pipeline'
WHATNEXT = ['coot_rebuild','prosmart_refmac',['buccaneer_build_refine_mr','$CCP4I2/pipelines/buccaneer_build_refine_mr/script/bucref_after_experimental.params.xml']]
MGDISPLAYFILES = ['XYZOUT']
RANK=1
EXPORTMTZPARAMS = [ ['F_SIGFanom', 'F_SIGFanom2', 'F_SIGFanom3', 'F_SIGFanom4', 'F_SIGFnative'],
'FPHOUT_HL', 'FPHOUT_DIFF', 'FPHOUT_2FOFC', 'FPHOUT_DIFFANOM' ]
def __init__(self,parent):
CCP4TaskWidget.CTaskWidget.__init__(self,parent)
# definition of pipelines.
self.basepipe = crank2_basepipe.crank2_basepipe()
# these names will appear in the start/end pipeline drop-down menu
self.step_names = { "substrdet": "Substructure detection", "refatompick": "Substruct. improvement",
"phas": "Substructure phasing", "phdmmb": "Den.mod. & poly-Ala tracing",
"handdet": "Hand determination", "dmfull": "Density modification",
"building": "Model building", "ref": "Refinement" }
# a lot of params will need to be added here - params from gui1 can be used as a good starting point!
self.default_generation_triggers = [ 'SEQIN', 'F_SIGFanom','F_SIGFanom2','F_SIGFanom3', 'F_SIGFanom4','F_SIGFnative', 'NATIVE', 'MAD2',\
'F_SIGFanom_nonmtz','F_SIGFanom2_nonmtz','F_SIGFanom3_nonmtz', 'F_SIGFanom4_nonmtz','F_SIGFnative_nonmtz', \
'USE_COMB', 'SUBSTRDET_PROGRAM', 'SHELXCDE', 'DNAME','DNAME2','DNAME3','DNAME4']
self.default_generation_string_triggers = [ 'ATOM_TYPE', 'MONOMERS_ASYM', 'WAVELENGTH', 'RESIDUES_MON', \
'WAVELENGTH2','WAVELENGTH3','WAVELENGTH4','CELL_A','CELL_B','CELL_C','CELL_D','CELL_E','CELL_F','SPACEGROUP' ]
# a list of parameters that do not obey the crank2 naming style
# (this list is only used to check for possible typos - not critical, functionality not affected at all)
self.crank2_naming_exceptions = ("HANDDET_DMCYC","REF_EXCLUDE_FREE","COMB_PHDMMB_EXCLUDE_FREE","MBREF_EXCLUDE_FREE")
self.save_def_connect, self.save_user_connect = {}, {}
self.is_def_connect, self.is_user_connect = {}, {}
self.save_connect = { self.setDefaultParameters: (self.save_def_connect, self.is_def_connect),
self.setByUser: (self.save_user_connect, self.is_user_connect),
}
self.defstr_act = {}
# saving the input data file path + type to check whether they changed and only generate defaults if they did
# to fight with i2 often changing the objects unneceserilly and slowing down the interface responsiveness
self.prev_data={'F_SIGFanom':(None,None),'F_SIGFanom2':(None,None),'F_SIGFanom3':(None,None),'F_SIGFanom4':(None,None),'F_SIGFnative':(None,None)}
self.job_started=False
def getcont(self,strng,cont=None):
if cont is None:
cont = self.container
if hasattr(cont.inputData,strng):
return getattr(cont.inputData,strng)
elif hasattr(cont.controlParameters,strng):
return getattr(cont.controlParameters,strng)
else:
return None
def ToggleDataInputMtz(self,nonmtz,mad):
return (mad=='' or self.getcont(mad)) and not self.getcont(nonmtz)
def ToggleDataInputNonMtz(self,nonmtz,mad):
return (mad=='' or self.getcont(mad)) and self.getcont(nonmtz)
def AddInputDataLine(self,fsigf,indent2,nonanom=False):
si = fsigf[-1] if fsigf.endswith(('2','3','4')) else ''
mad = 'MAD'+si if si else ''
if nonanom: mad = 'NATIVE'
if self.TASKNAME!='shelx' or nonanom:
self.createLine( [ 'label',indent2,'widget',fsigf+'_nonmtz' ], toggleFunction = [functools.partial(self.ToggleDataInputNonMtz,'NON_MTZ',mad), ['NON_MTZ',mad]] )
self.createLine( [ 'label',indent2,'widget',fsigf ], toggleFunction = [functools.partial(self.ToggleDataInputMtz,'NON_MTZ',mad), ['NON_MTZ',mad]] )
if not nonanom:
self.createLine( ['label', indent2+'Anomalous scatter. coef: ','label', "f':",'widget','FPRIME'+si, 'label', 'f":','widget','FDPRIME'+si,'label','wavelength:','widget','WAVELENGTH'+si,'widget','DNAME'+si], toggle = [ mad, 'open', [True]])
else:
self.createLine( [ 'label',indent2,'widget',fsigf+'_nonmtz','widget','DNAME'+si ], toggleFunction = [functools.partial(self.ToggleDataInputNonMtz,'NON_MTZ',mad), ['NON_MTZ',mad]] )
self.createLine( [ 'label',indent2,'widget',fsigf,'widget','DNAME'+si ], toggleFunction = [functools.partial(self.ToggleDataInputMtz,'NON_MTZ',mad), ['NON_MTZ',mad]])
def drawContents(self):
ctrl, inp = self.container.controlParameters, self.container.inputData
indent1 = ' '
indent2 = ' '
# parameters for which set-by-user is distinguished from crank2 defaults
self.set_by_user_params = [ (d[5:],ctrl) for d in ctrl._dataOrder if d.startswith('USER_') ] + \
[ (d[5:],inp) for d in inp._dataOrder if d.startswith('USER_') ]
self.setProgramHelpFile('crank2')
folder = self.openFolder(folderFunction='inputData',title='Input Data')
self.createLine( ['label', 'Start pipeline with', 'widget', 'START_PIPELINE', 'label', 'and end with', 'widget', 'END_PIPELINE'] )
if self.TASKNAME!='shelx':
self.createLine( ['subtitle','Input partial model (MR-SAD, model rebuilding)','If a partial protein model is available from molecular replacement or preliminary model building (for SAD only)','widget','INPUT_PARTIAL'] )
self.openSubFrame( toggle = [ 'INPUT_PARTIAL', 'open', [True]] )
self.createLine( [ 'label', indent1,'widget','XYZIN' ] )
self.createLine( [ 'label', indent1+'Start from anomalous substructure only - remove all non-substructure atoms','widget','PARTIAL_AS_SUBSTR' ] )
self.closeSubFrame()
#self.openSubFrame( toggle = [ 'INPUT_PARTIAL', 'open', [False]] )
#self.closeSubFrame()
self.createLine( [ 'subtitle', 'Input protein sequence ', 'widget', 'INPUT_SEQUENCE' ] )
self.openSubFrame( toggle = [ 'INPUT_SEQUENCE', 'open', [True]] )
self.createLine( [ 'label',indent1,'widget','SEQIN' ] )
infoline=self.createLine( [ 'advice', indent1+indent1+'In total', ], toggleFunction = [self.ToggleSeq, ['SEQIN','RESIDUES_MON']] )
infoline.addWidget( CCP4Widgets.CStringView(self, model=inp.RESIDUES_MON_INFO, qualifiers={'editable':False}) )
self.createLine( [ 'advice', 'residues found in the sequence.' ], appendLine=infoline )
self.closeSubFrame()
self.openSubFrame( toggle = [ 'INPUT_SEQUENCE', 'open', [False]] )
self.createLine( ['label', indent1+'Number of residues per monomer', 'widget', 'RESIDUES_MON_COPY'])
self.closeSubFrame()
#self.openSubFrame( toggle = [ 'DNA', 'open', [True]] )
#self.createLine( ['label', 'Number of nucleotides per monomer', 'widget', 'NUCLEOTIDES_MON'])
#self.closeSubFrame()
self.createLine( ['subtitle','Input starting phases','widget','INPUT_PHASES'], toggleFunction = [self.TogglePhases, ['START_PIPELINE','INPUT_PARTIAL']] )
self.openSubFrame( toggle=['INPUT_PHASES','open',[True]] )
self.createLine( ['widget','FPHIN_HL'] )
self.closeSubFrame()
self.createLine(['subtitle', 'Crystal #1 composition and collected anomalous dataset(s)', 'Specify the anomalously scattering atoms and dataset(s) for crystal used for phasing.'])
self.openSubFrame(frame=False)
#at_line=self.createLine(['label', indent1+'Substructure atom:','widget','ATOM_TYPE'])
#self.createLine( ['label', indent1+'Number of substructure atoms in asym. unit:','widget','NUMBER_SUBSTRUCTURE'], \
# appendLine=at_line, toggle = [ 'ATOM_TYPE', 'close', ['S']] )
#self.createLine( ['label', ' Sulphurs in asym. unit:','widget','NUMBER_SUBSTRUCTURE',\
# 'label',', forming ','widget','SUBSTRDET_NUM_DSUL','label','disulphides'], \
# appendLine=at_line, toggle = [ 'ATOM_TYPE', 'open', ['S']] )
at_line=self.createLine(['label', indent1+'Substructure atom:','widget','ATOM_TYPE','label','Number of substr. atoms in asymmetric unit:','widget','NUMBER_SUBSTRUCTURE'])
self.createLine( ['label',indent1+'Number of S-S pairs searched for as 1 supersulfur: ','widget','SUBSTRDET_NUM_DSUL'], toggleFunction = [self.ToggleDSUL, ['ATOM_TYPE','START_PIPELINE']] )
#at_line.addWidget( CCP4Widgets.CStringView(self, model=inp.ATOM_TYPE, qualifiers={'editable':False}) )
#self.createLine( ['label','in AU:','widget','NUMBER_SUBSTRUCTURE'], appendLine=at_line )
#self.createLine( ['label',', forming ','widget','NUMBER_SUBSTRUCTURE_DISULPHIDES','label','disulphides'], appendLine=at_line, toggle = [ 'ATOM_TYPE', 'open', ['S']] )
self.openSubFrame(toggleFunction = [self.ToggleSubstrModel, ['START_PIPELINE',]])
self.createLine( ['label',indent1+'Substructure','widget','XYZIN_SUB' ] )
self.closeSubFrame()
self.openSubFrame( toggle = [ 'NON_MTZ', 'open', [True]] )
self.createLine( ['label',indent1+'Cell:','widget','CELL_A','widget','CELL_B','widget','CELL_C',\
'widget','CELL_D','widget','CELL_E','widget','CELL_F','label',' Spacegroup:','widget','SPACEGROUP'] )
self.closeSubFrame()
self.openSubFrame(frame=True)
self.createLine( [ 'advice',indent1+'Anomalous data (Friedel pairs)','label',indent1+'Input unmerged/merged SCA/XDS/SHELX format','widget','NON_MTZ' ] )
self.AddInputDataLine('F_SIGFanom',indent2)
self.closeSubFrame()
self.openSubFrame(frame=True, toggle=['INPUT_PARTIAL','close',[True]])
self.createLine( [ 'label', indent1+'Input anomalous data #2 (MAD)', 'widget', 'MAD2'] )
self.AddInputDataLine('F_SIGFanom2',indent2)
self.closeSubFrame()
self.openSubFrame(frame=True, toggleFunction = [self.ToggleMAD3input, ['INPUT_PARTIAL','MAD2','MAD3']])
self.createLine( [ 'label', indent1+'Input anomalous data #3 (MAD)', 'widget', 'MAD3'] )
self.AddInputDataLine('F_SIGFanom3',indent2)
self.closeSubFrame()
self.openSubFrame(frame=True, toggleFunction = [self.ToggleMAD4input, ['INPUT_PARTIAL','MAD3','MAD4']])
self.createLine( [ 'label', indent1+'Input anomalous data #4 (MAD)', 'widget', 'MAD4'] )
self.AddInputDataLine('F_SIGFanom4',indent2)
self.closeSubFrame()
self.createLine( [ 'subtitle', 'Input native observations (Crystal #2)', 'Specify "native" data from a crystal to be modelled, if available', 'widget', 'NATIVE'] )
self.openSubFrame(frame=True,toggle = ['NATIVE', 'open', [True] ])
self.AddInputDataLine('F_SIGFnative',indent2='',nonanom=True)
#self.openSubFrame(toggle = ['NATIVE', 'open', [True] ] )
self.createLine( [ 'label', indent1+'Substructure atoms present in the native crystal', 'widget', 'SUBSTR_ATOMS_NATIVE' ] )
self.closeSubFrame()
freeline = self.createLine( ['subtitle', 'Exclude free ','widget','FREE'], toggleFunction = [self.ToggleFree,['END_PIPELINE']] )
self.createLine( ['label',' :','widget','FREERFLAG'], appendLine=freeline, toggle = ['FREE', 'open', ['existing'] ] )
self.createLine( ['label',' constisting of ','widget','FREE_RATIO','label', '% of reflections'], appendLine=freeline, toggle = ['FREE', 'open', ['new'] ] )
self.openFolder(title='Important Options', drawFolder=self.drawImportant)
self.openFolder(title='Advanced Options', drawFolder=self.drawAdvanced)
if self.TASKNAME=='shelx' and not inp.ATOM_TYPE.isSet():
inp.ATOM_TYPE.set('Se')
# sending the signal to mark set-by-user
# qt apparently sends this also when changed manually by defaults and blocking signals did not work,
# so we reset afterwards in that case at the end of SetI2DefPar
for p,cont in self.set_by_user_params:
#self.connect(getattr(cont,p), QtCore.SIGNAL('dataChanged'), self.setByUser(self,p,cont))
#self.connect(getattr(cont,p), QtCore.SIGNAL('dataChanged'), functools.partial(self.setByUser,p))
self.ConnectOneTrig(p,getattr(cont,p),partial=True,funct=self.setByUser)
# use FREE_EXISTING by default if supplied by i2 (is this safe?) - this certainly cannot be done here as cloned job could start with different assignments!
#if self.isEditable() and bool(str(inp.FREERFLAG).strip()):
# inp.FREE_EXISTING.set(True), inp.FREE_NEW.set(False)
# SAD/MAD
self.connect( inp.EXPTYPE, QtCore.SIGNAL('dataChanged'), self.SetSAD )
self.connect( inp.MAD2, QtCore.SIGNAL('dataChanged'), self.SADorMAD )
self.connect( inp.MAD3, QtCore.SIGNAL('dataChanged'), self.SADorMAD )
self.connect( inp.MAD4, QtCore.SIGNAL('dataChanged'), self.SADorMAD )
self.connect( inp.NON_MTZ, QtCore.SIGNAL('dataChanged'), self.SADorMAD )
self.connect( inp.NON_MTZ, QtCore.SIGNAL('dataChanged'), self.CellSpacegroup )
self.connect( inp.NATIVE, QtCore.SIGNAL('dataChanged'), self.InputNative )
self.connect( inp.ATOM_TYPE, QtCore.SIGNAL('dataChanged'), self.InputNative )
self.connect( inp.NON_MTZ, QtCore.SIGNAL('dataChanged'), self.InputNative )
self.connect( inp.ATOM_TYPE, QtCore.SIGNAL('dataChanged'), self.SSAD )
self.connect( inp.START_PIPELINE, QtCore.SIGNAL('dataChanged'), self.InputModelPhases )
self.connect( inp.START_PIPELINE, QtCore.SIGNAL('dataChanged'), self.AdjustEndPipeline )
self.connect( inp.END_PIPELINE, QtCore.SIGNAL('dataChanged'), self.SetFree )
self.connect( inp.SHELXCDE, QtCore.SIGNAL('dataChanged'), self.SetPipeline )
self.connect( inp.INPUT_PARTIAL, QtCore.SIGNAL('dataChanged'), self.SetPipeline )
self.connect( inp.INPUT_PARTIAL, QtCore.SIGNAL('dataChanged'), self.InputModelPhases )
self.connect( inp.EXPTYPE, QtCore.SIGNAL('dataChanged'), self.SetPipeline )
# sequence inputted or not
self.connect( inp.INPUT_SEQUENCE, QtCore.SIGNAL('dataChanged'), self.InputSequence )
# the residues_mon from basic options is equal to residues_mon from input data
# (the reason why they are separated is the fact that i2 would draw the red boxes in basic options but we need them in input data)
self.connect( inp.RESIDUES_MON_COPY, QtCore.SIGNAL('dataChanged'), self.InputResidues )
self.connect( inp.RESIDUES_MON, QtCore.SIGNAL('dataChanged'), self.InputResidues2 )
# connect the defaults generation triggers
self.ConnectDefaultGenTrig()
self.ConnectDefaultGenStringTrig()
# to make sure a new job is properly initialized incl. the red boxes
if self.isEditable():
self.AdjustEndPipeline()
self.CellSpacegroup()
self.InputSequence(init=True)
self.SADorMAD(init=True)
self.InputNative(init=True)
self.SSAD()
self.InputModelPhases()
#folder = self.openFolder(folderFunction='controlParameters',title='Important Options')
def drawImportant(self):
ctrl, inp = self.container.controlParameters, self.container.inputData
indent1 = ' '
indent2 = ' '
self.createLine(['label', 'Residues/monomer:','widget', 'RESIDUES_MON', \
'label', ' NCS copies:', 'widget', 'MONOMERS_ASYM', \
'label', ' Solvent Content: ', 'widget', 'SOLVENT_CONTENT' ])
self.openSubFrame(toggle = ['DNA', 'open', [True] ] )
self.createLine(['label', 'Nucleotides per monomer:','widget', 'NUCLEOTIDES_MON'])
self.closeSubFrame()
#self.createLine( ['widget','REPLACE_MET_MSE','label','Replace methionones by selenomethionine in the input partial model'])
self.openSubFrame(toggleFunction = [self.ToggleSADSIRASOption,['EXPTYPE','NATIVE']])
self.setMenuText('EXPTYPE',{'SAD':'SAD','SIRAS':'SIRAS','MAD':''})
self.createLine( [ 'label', 'Use ', 'widget', 'EXPTYPE', 'label', ' phasing and phase improvement'] )
self.closeSubFrame()
#self.createLine(['label',''])
#self.createLine(['label','Job output presentation style ','widget','PRESENT_STYLE'])
#self.createLine(['label', 'exclude free reflection as defined in UNSSIGNED'])
#self.createLine(['label', 'Create new free set to exclude ', 'label', ' of reflections'])
# connect the defaults generation triggers - needs to be done again due to separate tabs
self.ConnectDefaultGenTrig()
self.ConnectDefaultGenStringTrig()
def drawAdvanced(self):
#folder = self.openFolder(folderFunction='controlParameters',title='Advanced Options')
ctrl, inp = self.container.controlParameters, self.container.inputData
indent1 = ' '
indent2 = ' '
self.createLine(['advice', indent2+' Note: empty input fields mean that internal program defaults will be used.'])
if self.TASKNAME!='shelx':
# probably input partial not true needs to be added here!
self.createLine( ['label', 'Use SHELXC/D/E ','widget','SHELXCDE'], toggleFunction = [self.ToggleSHELXCDE,['START_PIPELINE','INPUT_PARTIAL']] )
substrdet_toggle,substrdet_toggle_not = [self.basepipe.ToggleDetection,['START_PIPELINE','INPUT_PARTIAL']], [self.basepipe.ToggleNotDetection,['START_PIPELINE','INPUT_PARTIAL']]
self.openSubFrame(frame=False, toggleFunction = substrdet_toggle)
self.createLine(['subtitle', 'Substructure detection'])
if self.TASKNAME!='shelx':
self.createLine(['label', indent2+'FA Estimation program: ', 'widget', 'FAEST_PROGRAM', 'label', indent1+'Detection program: ', 'widget', 'SUBSTRDET_PROGRAM'])
self.createLine(['label', indent2+'Initial high resol. cutoff:', 'widget', 'SUBSTRDET_HIGH_RES_CUTOFF', 'label', indent1+'Cutoff radius:','widget','SUBSTRDET_HIGH_RES_CUTOFF_RADIUS', 'label', indent1+'Cutoff step:', 'widget', 'SUBSTRDET_HIGH_RES_CUTOFF_STEP'], \
toggle = ['SUBSTRDET_PROGRAM', 'open', ['prasa']] )
self.createLine(['label', indent2+'High resolution cutoff:', 'widget', 'SUBSTRDET_HIGH_RES_CUTOFF'], \
toggle = ['SUBSTRDET_PROGRAM', 'open', ['shelxd','crunch2']] )
self.createLine(['label', indent2+'Use CCanom1/2 based cutoff (if available):', 'widget', 'SUBSTRDET_HIGH_RES_CUTOFF_CCHALF'], \
toggleFunction = [self.ToggleCChalf_rescut,['FAEST_PROGRAM','NON_MTZ']] )
plin=self.createLine(['label', indent2+'Num. trials:','widget','SUBSTRDET_NUM_TRIALS', 'label', indent1+'CFOM threshold:', 'widget', 'SUBSTRDET_THRESHOLD_STOP'] )
self.createLine( ['label', indent1+'Use num. atoms restraint','widget','PRASA_NUM_ATOMS_RESTR'], \
appendLine=plin, toggle = [ 'SUBSTRDET_PROGRAM', 'open', ['prasa']] )
#self.createLine( ['label', indent1+'','widget','SUBSTRDET_NUM_ATOMS'], \
# appendLine=plin2, toggle = [ 'PRASA_NUM_ATOMS_RESTR', 'open', [True]] )
self.createLine(['label', indent2+'Minimum distance between atoms: ', 'widget', 'SUBSTRDET_MIN_DIST_ATOMS', 'label', 'Å'+indent1+'Atoms in special positions allowed:','widget','SUBSTRDET_MIN_DIST_SYMM_ATOMS'], toggle = ['SUBSTRDET_PROGRAM', 'close', ['crunch2'] ])
#self.createLine(['label', indent2+'CFOM threshold: ', 'widget', 'SUBSTRDET_THRESHOLD_STOP', 'label', ' Number of trials:','widget','SUBSTRDET_NUM_TRIALS'])
self.createLine( ['label', indent2+'Number of CPU threads','widget','SUBSTRDET_NUM_THREADS'], \
toggle = [ 'SUBSTRDET_PROGRAM', 'open', ['shelxd','prasa']] )
self.createLine(['label', indent2+'Custom program keywords (comma separated)', 'widget', 'KEYWORDS_SUBSTRDET'])
self.closeSubFrame()
self.openSubFrame(frame=False, toggleFunction = [self.basepipe.TogglePeakSearch,['START_PIPELINE','INPUT_PARTIAL','EXPTYPE','SHELXCDE']])
self.createLine(['subtitle', 'Substructure improvement'])
#self.createLine(['label', indent2+'Refinement program: ', 'widget', 'REFATOMPICK_REF_PROGRAM'])
#self.createLine(['label', 'Keywords ', 'widget', 'KEYWORDS_PEAK'])
self.createLine(['label', indent2+'Max. num. of iterations: ', 'widget', 'REFATOMPICK_NUM_ITER', 'label', indent1+'Number of ref. cycles per iteration ','widget','REFATOMPICK_REFCYC'])
self.createLine(['label', indent2+'Minimum RMS required in map to add new atom: ', 'widget', 'REFATOMPICK_RMS_THRESHOLD'])
self.closeSubFrame()
self.openSubFrame(frame=False, toggleFunction=[self.basepipe.TogglePhasing,['END_PIPELINE','SHELXCDE','INPUT_PARTIAL','PARTIAL_AS_SUBSTR','EXPTYPE']])
self.createLine(['subtitle', 'Substructure phasing'])
self.createLine(['label', indent2+'Phasing program: ', 'widget', 'PHAS_PROGRAM'])
#self.createLine(['label', 'Keywords', 'widget', 'KEYWORDS_PHAS'])
self.closeSubFrame()
self.openSubFrame(frame=False, toggleFunction=[self.basepipe.ToggleHandDetermination,['END_PIPELINE','SHELXCDE','INPUT_PARTIAL','PARTIAL_AS_SUBSTR','DO_HANDDET']])
self.createLine(['subtitle', 'Hand determination', 'widget','DO_HANDDET'])
#self.createLine(['label', indent2+'Number of iterations: ', 'widget', 'HANDDET_DMCYC'])
self.createLine(['label', indent2+'Density modif. program:', 'widget', 'HANDDET_DMFULL_DM_PROGRAM','label', indent1+'Phase combination program: ', 'widget', 'HANDDET_DMFULL_PHCOMB_PROGRAM'], \
toggleFunction=[self.ToggleHandDeterminationDoHand,['END_PIPELINE','SHELXCDE','INPUT_PARTIAL','PARTIAL_AS_SUBSTR','DO_HANDDET']])
#self.createLine(['label', 'Keywords for dens.mod.program', 'widget', 'KEYWORDS_HANDDET_DM'])
#self.createLine(['label', indent2+'Phase combination program: ', 'widget', 'HANDDET_DMFULL_PHCOMB_PROGRAM'])
# self.createLine(['label', 'Keywords for Phase combination program', 'widget', 'KEYWORDS_HANDDET_PHCOMB'])
self.closeSubFrame()
self.openSubFrame(frame=False, toggleFunction=[self.basepipe.ToggleDensityModification,['END_PIPELINE','SHELXCDE','INPUT_PARTIAL','PARTIAL_AS_SUBSTR']])
self.createLine(['subtitle', 'Density modification'])
self.createLine(['label', indent2+'Density modif. program:', 'widget', 'DMFULL_DM_PROGRAM','label', indent1+'Phase combination program: ', 'widget', 'DMFULL_PHCOMB_PROGRAM'])
#self.createLine(['label', indent2+'Phase combination program: ', 'widget', 'DMFULL_PHCOMB_PROGRAM'])
self.createLine(['label', indent2+'Number of iterations: ', 'widget', 'DMFULL_DMCYC', 'label', indent1+'FOM threshold: ', 'widget', 'DMFULL_THRESHOLD_STOP'])
self.createLine(['label', indent2+'Custom options for dens.mod. program:', 'widget', 'KEYWORDS_DMFULL_DM'])
# self.createLine(['label', 'Keywords for Phase combination program', 'widget', 'KEYWORDS_DMFULL_PHCOMB'])
self.closeSubFrame()
self.openSubFrame(frame=False, toggleFunction=[self.basepipe.ToggleShelxCDE,['END_PIPELINE','SHELXCDE','INPUT_PARTIAL']] )
self.createLine(['subtitle', 'Density modification and poly-Ala tracing with SHELXE'])
self.createLine(['label', indent2+'Number of density modif. cycles: ', 'widget', 'PHDMMB_DMCYC', \
'label', indent1+'Number of model building cycles: ', 'widget', 'PHDMMB_BIGCYC'])
self.createLine(['label', indent2+'CC threshold: ', 'widget', 'PHDMMB_THRESHOLD_STOP', 'label', ' Other hand CC threshold: ', 'widget', 'PHDMMB_THRESHOLD_HAND_STOP'])
self.createLine(['label', indent2+'Use thorough building if CFOM from substr. detection is smaller than', 'widget', 'SUBSTRDET_THRESHOLD_WEAK'], toggleFunction=substrdet_toggle)
self.createLine(['label', indent2+'Use thorough building', 'widget', 'PHDMMB_THOROUGH_BUILD'], toggleFunction=substrdet_toggle_not)
self.createLine(['label', indent2+'Custom program arguments (comma separated)', 'widget', 'ARGUMENTS_SHELXE'])
self.closeSubFrame()
self.openSubFrame(frame=False,toggleFunction=[self.basepipe.ToggleModelBuilding,['END_PIPELINE','INPUT_PARTIAL']])
self.createLine(['subtitle', 'Model building'])
self.createLine(['label', indent2+'Combine phase, model and density modif. information ', 'widget', 'USE_COMB'], toggle = [ 'MB_PROGRAM', 'close', ['arpwarp']] )
mb_prog_line=self.createLine(['label', indent2+'Model building program: ', 'widget', 'MB_PROGRAM'])
mb_toggle=[self.basepipe.ToggleUseComb,['USE_COMB','END_PIPELINE','INPUT_PARTIAL','MB_PROGRAM']]
self.createLine(['label', indent2+'Density modif. program: ', 'widget', 'COMB_PHDMMB_DMFULL_DM_PROGRAM'], toggleFunction=mb_toggle, appendLine=mb_prog_line)
self.createLine(['label', indent2+'Custom keywords for building program:', 'widget', 'KEYWORDS_MB'])
self.createLine(['label', indent2+'Custom keywords for dens.mod. program:', 'widget', 'KEYWORDS_COMB_DM'], toggleFunction=mb_toggle)
self.createLine(['label', indent2+'Start with a few SHELXE tracing cycles', 'widget', 'COMB_PHDMMB_START_SHELXE', 'label', 'with custom keywords', 'widget', 'KEYWORDS_COMB_SHELXE'], toggleFunction=mb_toggle)
#self.createLine(['label', 'Keywords for building program:', 'widget', 'KEYWORDS_MB'])
#self.createLine(['label', 'Keywords for refinement program:', 'widget', 'KEYWORDS_MB_REF'])
self.openSubFrame(frame=False, toggleFunction=mb_toggle)
#self.createLine(['label', indent2+'Refinement program: ', 'widget', 'COMB_PHDMMB_DMFULL_REF_PROGRAM'])
#self.createLine(['label', indent2+'DM program: ', 'widget', 'COMB_PHDMMB_DMFULL_DM_PROGRAM'])
self.createLine(['label', indent2+'Minimum number of cycles: ', 'widget', 'COMB_PHDMMB_MINBIGCYC', 'label', indent1+'Maximum number of cycles: ', 'widget', 'COMB_PHDMMB_MAXBIGCYC'])
ncs_line=self.createLine(['label', indent2+'Try to determine NCS', 'widget', 'COMB_PHDMMB_NCS_DET'], toggleFunction=[self.basepipe.ToggleNCS,['COMB_PHDMMB_DMFULL_DM_PROGRAM','MONOMERS_ASYM'] ] )
self.createLine(['label', indent1+'from partial model (rather than heavy atoms)', 'widget', 'COMB_PHDMMB_NCS_DET_MR'], \
appendLine=ncs_line, toggle = [ 'COMB_PHDMMB_NCS_DET', 'open', [True]] )
self.createLine(['label', indent2+'Skip the first model building cycle', 'widget', 'COMB_PHDMMB_SKIP_INITIAL_BUILD', 'label',indent1+'Soft rebuilding','widget','COMB_PHDMMB_REBUILD_ONLY'])
self.createLine(['label', indent2+'Exclude the free reflections in model building ', 'widget', 'COMB_PHDMMB_EXCLUDE_FREE'], toggle = ['FREE', 'close', ['no']] )
self.closeSubFrame()
self.openSubFrame(frame=False, toggleFunction=[self.ToggleNoUseComb,['USE_COMB','END_PIPELINE','INPUT_PARTIAL','MB_PROGRAM']])
#self.createLine(['label', indent2+'Refinement program: ', 'widget', 'MBREF_REF_PROGRAM'])
self.createLine(['label', indent2+'Number of building cycles: ', 'widget', 'MBREF_BIGCYC'])
self.createLine(['label', indent2+'Exclude the free reflections in model building ', 'widget', 'MBREF_EXCLUDE_FREE'], toggle = ['FREE', 'close', ['no']] )
self.closeSubFrame()
self.closeSubFrame()
self.openSubFrame(frame=False,toggleFunction=[self.basepipe.ToggleRefine,['END_PIPELINE','INPUT_PARTIAL']])
self.createLine(['subtitle', 'Final model refinement with REFMAC'])
#self.createLine(['label', indent2+'Refinement program: ', 'widget', 'REF_PROGRAM'])
self.createLine(['label', indent2+'Number of refinement cycles: ', 'widget', 'REF_CYCLES'])
self.createLine(['label', indent2+'Exclude the free reflections in refinement ', 'widget', 'REF_EXCLUDE_FREE'], toggle = ['FREE', 'close', ['no']] )
#self.createLine(['label', 'Keywords for refinement program:', 'widget', 'KEYWORDS_REF'])
#self.createLine(['advice', 'Separate any keywords with commas'])
self.closeSubFrame()
self.createLine(['label', 'Remove all intermediate mtz files at the end?', 'widget', 'CLEANUP'])
# connect the defaults generation triggers - needs to be done again due to separate tabs
self.ConnectDefaultGenTrig()
self.ConnectDefaultGenStringTrig()
def InputResidues(self):
self.container.inputData.RESIDUES_MON = self.container.inputData.RESIDUES_MON_COPY
def InputResidues2(self):
self.container.inputData.RESIDUES_MON_INFO.set( ''+str(self.container.inputData.RESIDUES_MON)+'' )
def SetPipeline(self,base_steps_only=False):
self.basepipe.SetBaseSteps(self.container)
if not base_steps_only:
inp,ctrl=self.container.inputData,self.container.controlParameters
self.SetI2DefPar(ctrl, 'DO_HANDDET', False) if inp.INPUT_PARTIAL else self.SetI2DefPar(ctrl, 'DO_HANDDET', True)
prev_start = str(inp.START_PIPELINE)
inp.START_PIPELINE.setQualifier('enumerators', types.ListType( self.basepipe.base_steps ))
inp.START_PIPELINE.setQualifier('menuText', types.ListType( [self.step_names[s] for s in self.basepipe.base_steps] ))
if prev_start in inp.START_PIPELINE.qualifiers('enumerators'):
inp.START_PIPELINE.set(prev_start)
else:
inp.START_PIPELINE.set(self.basepipe.base_steps[0])
if self.getWidget('START_PIPELINE'):
self.getWidget('START_PIPELINE').validate()
self.getWidget('START_PIPELINE').populateComboBox(model = inp.START_PIPELINE)
self.getWidget('START_PIPELINE').updateViewFromModel()
self.AdjustEndPipeline()
def AdjustEndPipeline(self,step=None):
# this will need to be changed for MR-SAD and SHELX...
inp=self.container.inputData
if step is None:
step = str(inp.START_PIPELINE)
prev_end = str(inp.END_PIPELINE)
end_steps = self.basepipe.base_steps[self.basepipe.base_steps.index(step):]
inp.END_PIPELINE.setQualifier('enumerators', types.ListType( end_steps ))
inp.END_PIPELINE.setQualifier('menuText', types.ListType( [self.step_names[s] for s in end_steps] ))
if prev_end in inp.END_PIPELINE.qualifiers('enumerators') and prev_end!='ref':
inp.END_PIPELINE.set(prev_end)
else:
#inp.END_PIPELINE.set("ref")
inp.END_PIPELINE.set("building")
if self.getWidget('END_PIPELINE'):
self.getWidget('END_PIPELINE').validate()
self.getWidget('END_PIPELINE').populateComboBox(model = inp.END_PIPELINE)
self.getWidget('END_PIPELINE').updateViewFromModel()
def SetFree(self):
if not self.ToggleFree():
self.container.inputData.FREE.set('no')
def InputModelPhases(self):
if self.TASKNAME!='shelx':
self.container.inputData.XYZIN.setQualifier( 'allowUndefined', not bool(self.container.inputData.INPUT_PARTIAL) )
self.getWidget('XYZIN').validate()
self.container.inputData.ATOM_TYPE.setQualifier( 'allowUndefined', False )
self.getWidget('ATOM_TYPE').validate()
self.container.inputData.XYZIN_SUB.setQualifier( 'allowUndefined', not self.ToggleSubstrModel() or bool(self.container.inputData.INPUT_PARTIAL) )
self.getWidget('XYZIN_SUB').validate()
if bool(self.container.inputData.INPUT_PHASES) and not self.TogglePhases():
self.container.inputData.INPUT_PHASES.set(False)
self.container.inputData.FPHIN_HL.setQualifier( 'allowUndefined', not self.container.inputData.INPUT_PHASES )
self.getWidget('FPHIN_HL').validate()
def ToggleCChalf_rescut(self):
return str(self.container.controlParameters.FAEST_PROGRAM)=='shelxc' and bool(self.container.inputData.NON_MTZ)
def ToggleSubstrModel(self):
return str(self.container.inputData.START_PIPELINE) in ['phdmmb','phas','handdet','dmfull','building','ref','refatompick' ]
def ToggleDSUL(self):
return self.basepipe.CheckStartEnd('substrdet') and str(self.container.inputData.ATOM_TYPE)=='S'
def TogglePhases(self):
# input of phases to shelxe not supported as of now although technically possible
return str(self.container.inputData.START_PIPELINE) in ['handdet','dmfull','building','ref' ] or bool(self.container.inputData.INPUT_PARTIAL)
def ToggleSHELXCDE(self):
return str(self.container.inputData.START_PIPELINE) in ['substrdet','phas','phdmmb','refatompick'] and not bool(self.container.inputData.INPUT_PARTIAL)
def ToggleSeq(self):
return bool(str(self.container.inputData.SEQIN).strip())
def ToggleMAD3input(self):
inp = self.container.inputData
return not inp.INPUT_PARTIAL and (inp.MAD2 or inp.MAD3)
def ToggleMAD4input(self):
inp = self.container.inputData
return not inp.INPUT_PARTIAL and (inp.MAD3 or inp.MAD4)
def InputSequence(self,init=False):
inp=self.container.inputData
inp.SEQIN.setQualifier( 'allowUndefined', not bool(inp.INPUT_SEQUENCE) )
self.getWidget('SEQIN').validate()
inp.RESIDUES_MON_COPY.setQualifier( 'mustExist', not bool(inp.INPUT_SEQUENCE) )
inp.RESIDUES_MON_COPY.setQualifier( 'allowUndefined', bool(inp.INPUT_SEQUENCE) )
self.getWidget('RESIDUES_MON_COPY').validate()
if not init and inp.INPUT_SEQUENCE:
inp.USER_RESIDUES_MON.set(False)
def ConnectDefaultGenStringTrig(self):
for trig in self.default_generation_string_triggers:
#self.connect( self.getWidget(trig.objectName()).widget, QtCore.SIGNAL('editingFinished()'), self.setDefaultParameters )
if self.getWidget(trig) and hasattr(self.getWidget(trig),'widget'):
self.defstr_act[trig] = [False, False]
self.connect( self.getWidget(trig).widget, QtCore.SIGNAL('editingFinished()'), functools.partial(self.DefStrTrig0,trig) )
self.connect( self.getcont(trig), QtCore.SIGNAL('dataChanged'), functools.partial(self.DefStrTrig1,trig) )
# making sure that both editingFinished and dataChanged is connected to prevent useless def. generation
def DefStrTrig0(self,trig):
self.defstr_act[trig][0] = True
if self.defstr_act[trig][1]:
self.defstr_act[trig][0], self.defstr_act[trig][1] = False, False
self.setDefaultParameters(trig)
def DefStrTrig1(self,trig):
self.defstr_act[trig][1] = True
if self.defstr_act[trig][0]:
self.defstr_act[trig][0], self.defstr_act[trig][1] = False, False
self.setDefaultParameters(trig)
def ConnectOneTrig(self,trig,obj,disconnect=False,partial=True,funct=None):
# assuming default generation triggers by default
if funct is None:
funct = self.setDefaultParameters
saved_conn = self.save_connect[funct][0]
is_conn = self.save_connect[funct][1]
if partial and trig not in saved_conn:
saved_conn[trig] = functools.partial(funct,trig)
defpar = saved_conn[trig] if partial and trig in saved_conn else funct
if disconnect or trig not in is_conn or not is_conn[trig]:
action = self.connect if not disconnect else self.disconnect
action( obj, QtCore.SIGNAL('dataChanged'), defpar )
if disconnect:
is_conn[trig] = False
else:
is_conn[trig] = True
def ConnectDefaultGenTrig(self,trigs=None,disconnect=False,partial=True):
if not trigs:
trigs = self.default_generation_triggers
for trig in trigs:
obj = self.getcont(trig)
self.ConnectOneTrig(trig, obj, disconnect, partial)
# another default generation trigger seems to be needed for the contentFlag
# this is due to selecting a file from a previous job - the contentFlag appears to be set after the data object sends its dataChanged signal...
if trig.startswith('F_SIGF') and not trig.endswith('_nonmtz'):
self.ConnectOneTrig(trig+'.contentFlag', getattr(obj,'contentFlag'), disconnect, partial)
def CellSpacegroup(self):
ctrl, inp = self.container.controlParameters, self.container.inputData
for var in ('CELL_A','CELL_B','CELL_C','CELL_D','CELL_E','CELL_F','SPACEGROUP'):
self.getcont(var).setQualifier('allowUndefined',not inp.NON_MTZ)
self.getWidget(var).validate()
def SADorMAD(self,init=False):
ctrl, inp = self.container.controlParameters, self.container.inputData
inp.F_SIGFanom.setQualifier( 'allowUndefined',bool(inp.NON_MTZ))
inp.F_SIGFanom_nonmtz.setQualifier( 'allowUndefined',not inp.NON_MTZ)
self.getWidget('F_SIGFanom').validate(), self.getWidget('F_SIGFanom_nonmtz').validate()
inp.F_SIGFanom2.setQualifier( 'allowUndefined',not inp.MAD2 or bool(inp.NON_MTZ))
inp.F_SIGFanom2_nonmtz.setQualifier( 'allowUndefined',not inp.MAD2 or not inp.NON_MTZ)
inp.DNAME2.setQualifier( 'allowUndefined',not inp.MAD2 )
self.getWidget('F_SIGFanom2').validate(), self.getWidget('F_SIGFanom2_nonmtz').validate()
self.getWidget('DNAME2').validate()
inp.F_SIGFanom3.setQualifier( 'allowUndefined',not inp.MAD3 or bool(inp.NON_MTZ))
inp.F_SIGFanom3_nonmtz.setQualifier( 'allowUndefined',not inp.MAD3 or not inp.NON_MTZ)
inp.DNAME3.setQualifier( 'allowUndefined',not inp.MAD3 )
self.getWidget('F_SIGFanom3').validate(), self.getWidget('F_SIGFanom3_nonmtz').validate()
self.getWidget('DNAME3').validate()
inp.F_SIGFanom4.setQualifier( 'allowUndefined',not inp.MAD4 or bool(inp.NON_MTZ))
inp.F_SIGFanom4_nonmtz.setQualifier( 'allowUndefined',not inp.MAD4 or not inp.NON_MTZ)
inp.DNAME4.setQualifier( 'allowUndefined',not inp.MAD4 )
self.getWidget('F_SIGFanom4').validate(), self.getWidget('F_SIGFanom4_nonmtz').validate()
self.getWidget('DNAME4').validate(),
if not init:
if inp.MAD2 or inp.MAD3 or inp.MAD4:
#inp.EXPTYPE.set('MAD')
# once the default pipeline is set in crank2, this can/should be moved there
if self.container.controlParameters.USE_COMB:
self.container.controlParameters.USE_COMB.set(False)
else:
self.SetSAD()
self.InputNative()
# this could be removed once it is possible to input "wildcard" programs to crank2
if inp.MAD2 or inp.MAD3 or inp.MAD4 or (inp.EXPTYPE=='SIRAS' and inp.NATIVE):
ctrl.PHAS_PROGRAM.set('bp3')
ctrl.DMFULL_PHCOMB_PROGRAM.set('multicomb')
else:
ctrl.PHAS_PROGRAM.set('refmac')
ctrl.DMFULL_PHCOMB_PROGRAM.set('refmac')
def SetSAD(self):
ctrl, inp = self.container.controlParameters, self.container.inputData
#inp.EXPTYPE.set('SAD')
if self.TASKNAME!='shelx':
if inp.EXPTYPE=='SAD' and not ctrl.USE_COMB:
ctrl.USE_COMB.set(True)
if inp.EXPTYPE!='SAD' and ctrl.USE_COMB:
ctrl.USE_COMB.set(False)
def SSAD(self):
ctrl, inp = self.container.controlParameters, self.container.inputData
# this is in fact not only for S-SAD but also for all atoms that do not have wavelengths defined in crank2
inp.DNAME.setQualifier('allowUndefined', inp.EXPTYPE!='MAD' and (self.TASKNAME=='shelx' or \
str(inp.ATOM_TYPE).strip().upper() not in ('SE','HG','AU','PT','ZN','BR')) )
self.getWidget('DNAME').validate()
def InputNative(self,init=False):
ctrl, inp = self.container.controlParameters, self.container.inputData
inp.F_SIGFnative.setQualifier( 'allowUndefined',not inp.NATIVE or bool(inp.NON_MTZ) )
inp.F_SIGFnative_nonmtz.setQualifier( 'allowUndefined',not inp.NATIVE or not inp.NON_MTZ)
self.getWidget('F_SIGFnative').validate(), self.getWidget('F_SIGFnative_nonmtz').validate()
# once the default pipeline is set in crank2, this can/should be moved there
#if inp.NATIVE and inp.ATOM_TYPE.isSet() and not init:
# # disabled as of now for Crank2 as both refmac and bp3 crash for SIRAS ! enabled again.lets see whether it was fixed...
# if inp.EXPTYPE=='SAD' and str(inp.ATOM_TYPE).strip()!='S' : #and inp.SHELXCDE:
# inp.EXPTYPE.set('SIRAS')
# if self.container.controlParameters.USE_COMB:
# self.container.controlParameters.USE_COMB.set(False)
# if inp.EXPTYPE=='SIRAS' and str(inp.ATOM_TYPE).strip()=='S':
# self.SetSAD()
#if not inp.NATIVE and inp.EXPTYPE=='SIRAS':
self.SetSAD()
def ClearSavedF(self,si):
if not self.isEditable(): return
inp = self.container.inputData
self.ConnectDefaultGenTrig(disconnect=True)
getattr(inp,'SAVED_FAVFILE'+si).unSet()
if si!="_NATIVE":
getattr(inp,'SAVED_FPMFILE'+si).unSet()
if self.isEditable() and not self.job_started:
getattr(inp,'DNAME'+si).unSet(), getattr(inp,'WAVELENGTH'+si).unSet()
getattr(inp,'FPRIME'+si).unSet(), getattr(inp,'FDPRIME'+si).unSet()
getattr(inp,'USER_WAVELENGTH'+si).set(False), getattr(inp,'USER_DNAME'+si).set(False)
getattr(inp,'USER_FPRIME'+si).set(False), getattr(inp,'USER_FDPRIME'+si).set(False)
self.ConnectDefaultGenTrig()
def ToggleSADSIRASOption(self):
return self.container.inputData.NATIVE and self.container.inputData.EXPTYPE in ('SAD','SIRAS')
def ToggleHandDeterminationDoHand(self):
return self.container.controlParameters.DO_HANDDET and self.basepipe.ToggleHandDetermination()
def ToggleFree(self):
return self.basepipe.CheckStartEnd('ref') or self.basepipe.CheckStartEnd('building')
def ToggleNoUseComb(self):
return self.basepipe.CheckStartEnd('building') and not self.basepipe.ToggleUseComb()
# or self.container.inputData.INPUT_PARTIAL )
def AutoSetI2DefaultPar(self, proc_parent, i2cont, par, par_recur=None):
# tries to recursively find the corresponding default parameter in the proc_parent crank tree
# the i2 par names (defined in the crank2 i2 xml) must match the crank2 names for this to work
# returns 1 if parameter was set, 2 if it was not set and process not found, 0 if not set but process found
if par_recur is None:
par_recur=par
proc_nick, sep, key = par_recur.lower().partition('_')
# takes care of possible _ in the process nick
if proc_nick not in [p.nick for p in proc_parent.processes]:
proc_nick_add, sep, key = key.partition('_')
proc_nick += '_'+proc_nick_add
for proc in proc_parent.processes:
if self.SI2P( proc, i2cont, par, key, proc_nick ):
return 1
else:
for proc in proc_parent.processes:
if proc.nick == proc_nick:
if self.AutoSetI2DefaultPar(proc, i2cont, par, key)==1:
return 1
return 0
return 2
def SI2P(self, proc, i2cont, par, key, proc_nick):
# only called internally by SetI2DefaultPar
if proc.nick == proc_nick:
if key == 'program':
if proc.GetProg(supported=True):
self.SetI2DefPar(i2cont, par, proc.GetProg(supported=True).nick)
return 1
elif key in proc.supported_params:
self.SetI2DefPar(i2cont, par, proc.GetParam(key))
return 1
return 0
def CheckUse(self, cont, param):
# use this function for all parameters that can be set by default or by user
if getattr(cont,param).isSet() and ( not hasattr(cont,'USER_'+param) or getattr(cont,'USER_'+param) ):
return True
else:
return False
def SetI2DefPar(self,i2cont, par, value, allow_None=True, validate_widget=False, emulate=False):
# return 1 if somethign was (re)set, 0 if nothing changed
if not hasattr(i2cont,'USER_'+par) or not getattr(i2cont,'USER_'+par):
if (value is not None or allow_None) and (str(value)!=str(getattr(i2cont, par))):
con=getattr(i2cont, par)
if not emulate:
self.ConnectOneTrig(par,con,disconnect=True,partial=True,funct=self.setByUser)
#if value==False: value=0
#elif value==True: value=1
if value=='unSet()':
con.unSet()
else:
con.set(value)
self.ConnectOneTrig(par,con,partial=True,funct=self.setByUser)
if validate_widget and self.getWidget(par):
self.getWidget(par).validate()
return 1
return 0
def CheckDataChanged(self,inp,lab):
# checks whether data has changed and thus defaults need to be generated. returns 1 if yes, 0 if no
if inp.NON_MTZ:
return 1
path, flag = str(getattr(inp,lab).fullPath), getattr(inp,lab).contentFlag
# here we assume that input mtz will be converted to mini-mtz in ccp4 dir. without this we'd get
# double generation and thus slow response. However if mini-mtz is not created then no generation
# will take place - these two lines would have to be removed in such case!
from core.CCP4Modules import PROJECTSMANAGER
if not os.path.realpath(path).startswith(os.path.realpath(CCP4Utils.getTestTmpDir())) and \
not os.path.realpath(path).startswith(os.path.realpath(PROJECTSMANAGER().getProjectDirectory(projectId=self.projectId()))):
return 0
try:
flag = int(flag)
except:
flag = None
# we don't need to generate defaults if there is no change in the path and flag
if path==self.prev_data[lab][0] and flag==self.prev_data[lab][1]:
return 0
# saving the file path and content for the next check
if path is not None and flag is not None:
self.prev_data[lab]=(path,flag)
return 1
def setDefaultParameters(self,trig_by=None):
from core.CCP4PluginScript import CPluginScript
from core import CCP4XtalData
ctrl = self.container.controlParameters
inp = self.container.inputData
fsigf_supplied = True
print 'setDefaultParameters',trig_by
if trig_by is None:
if self.isEditable():
taskname=self.TASKNAME
if inp.SHELX_SEPAR:
self.TASKNAME='shelx'
if self.TASKNAME=='shelx':
inp.SHELX_SEPAR.set(True)
self.ConnectDefaultGenTrig(trigs=['SHELXCDE','USE_COMB'],disconnect=True)
inp.SHELXCDE.set(True)
ctrl.FAEST_PROGRAM.set('shelxc')
ctrl.SUBSTRDET_PROGRAM.set('shelxd')
ctrl.USE_COMB.set(False)
# different from the crank2 defaults - basically the (first) user is George here :)
#ctrl.MBREF_BIGCYC.set(2)
#ctrl.USER_MBREF_BIGCYC.set(True)
self.SetPipeline(base_steps_only=not self.isEditable())
if self.isEditable():
if taskname.startswith('crank2_') and taskname.split('_')[1] in self.basepipe.base_steps:
inp.START_PIPELINE.set( taskname.split('_')[1] )
if taskname in ('crank2_comb_phdmmb','crank2_mbref'):
inp.START_PIPELINE.set( 'building' )
inp.F_SIGFnative_nonmtz.contentFlag.set( CCP4XtalData.CObsDataFile.CONTENT_FLAG_IMEAN )
inp.F_SIGFanom_nonmtz.contentFlag.set( CCP4XtalData.CObsDataFile.CONTENT_FLAG_IPAIR )
inp.F_SIGFanom2_nonmtz.contentFlag.set( CCP4XtalData.CObsDataFile.CONTENT_FLAG_IPAIR )
inp.F_SIGFanom3_nonmtz.contentFlag.set( CCP4XtalData.CObsDataFile.CONTENT_FLAG_IPAIR )
inp.F_SIGFanom4_nonmtz.contentFlag.set( CCP4XtalData.CObsDataFile.CONTENT_FLAG_IPAIR )
if not ctrl.INITIAL_DEFAULTS_GEN:
print 'full setDefaultParameters not needed, quitting.'
return
else:
ctrl.INITIAL_DEFAULTS_GEN.set(False)
# we don't need to generate defaults if triggered by cell/spacegroup edit but not all supplied yet
if trig_by and (trig_by.startswith('CELL_') or trig_by.startswith('SPACEGROUP')):
if not inp.CELL_A or not inp.CELL_B or not inp.CELL_C or not inp.SPACEGROUP:
return
# clearing the SAVED F's info on new data input and checking whether the data change is relevant
# (irrelevant changes may be triggered by i2 itself rather than user)
if trig_by and trig_by.startswith('F_SIGFanom'):
# we don't need to generate defaults if triggered by non_mtz objects but the non_mtz option is off (and the other way around)
if ('_nonmtz' in trig_by and not inp.NON_MTZ) or ('_nonmtz' not in trig_by and inp.NON_MTZ):
return
si = trig_by[10] if len(trig_by)>10 and trig_by[10].isdigit() else ''
if not si or getattr(inp,'MAD'+si):
if not self.CheckDataChanged(inp,'F_SIGFanom'+si):
return
self.ClearSavedF(si)
else:
return
if trig_by and trig_by.startswith('F_SIGFnative'):
if ('_nonmtz' in trig_by and not inp.NON_MTZ) or ('_nonmtz' not in trig_by and inp.NON_MTZ):
return
if getattr(inp,'NATIVE'):
if not self.CheckDataChanged(inp,'F_SIGFnative'):
return
self.ClearSavedF('_NATIVE')
else:
return
# check whether all the needed datasets were supplied
for i in range(4):
si = str(i+1) if i else ''
sif = si+'_nonmtz' if inp.NON_MTZ else si
if (not si or getattr(inp,'MAD'+si)) and (not getattr(inp,'F_SIGFanom'+sif).fullPath.isSet() or \
not getattr(inp,'F_SIGFanom'+sif).contentFlag.isSet()) :
fsigf_supplied = False
break
if inp.NATIVE:
if not inp.NON_MTZ and (not inp.F_SIGFnative.fullPath.isSet() or not inp.F_SIGFnative.contentFlag.isSet()):
fsigf_supplied = False
if inp.NON_MTZ and (not inp.F_SIGFnative_nonmtz.fullPath.isSet() or not inp.F_SIGFnative_nonmtz.contentFlag.isSet()):
fsigf_supplied = False
if self.isEditable() and not self.job_started and \
( (trig_by and trig_by.startswith('SEQIN')) or fsigf_supplied ) and \
( (trig_by and trig_by.startswith('F_SIGF')) or (inp.SEQIN.isSet() or not inp.INPUT_SEQUENCE) ):
# check for multiple unassigned dnames and correct if it is the case
nodn=0
for dn,dnstr,use in [(inp.DNAME,'DNAME',True), (inp.DNAME2,'DNAME2',inp.MAD2), \
(inp.DNAME3,'DNAME3',inp.MAD3), (inp.DNAME4,'DNAME4',inp.MAD4)]:
if use and (not dn.isSet() or not dn):
if nodn:
self.ConnectDefaultGenTrig(disconnect=True)
self.SetI2DefPar( inp, dnstr, "unknown{}".format(nodn) )
self.ConnectDefaultGenTrig()
nodn+=1
print "Starting generating defaults."
self.ConnectDefaultGenTrig(disconnect=True)
try:
from core import CCP4Modules
workDir = CCP4Modules.PROJECTSMANAGER().jobDirectory(self.jobId(),subDir='TMP')
except:
workDir = None
try:
defaults = CPluginScript(dummy=True,workDirectory=workDir).makePluginObject(pluginName='crank2',reportToDatabase=False).process(self.container)
except Exception as e:
print "Exception caught when preparing the defaults: {}".format(e)
print traceback.print_exc()
if 'MATTHEWS_COEF' in str(e) and ('The SYMM keyword' in str(e) or 'SYMMETRY OPERATOR ERROR' in str(e)):
inp.SPACEGROUP.set(None)
else:
print "Defaults generation finished.",defaults
if defaults:
try:
# automatically setting defaults for the parameters named in the "crank2 way"
for cont_str in ('controlParameters','inputData'):
cont = getattr(self.container,cont_str)
for par in cont._dataOrder:
if not hasattr(cont,'USER_'+par) or not getattr(cont,'USER_'+par):
if not self.AutoSetI2DefaultPar(defaults, cont, par) and par not in self.crank2_naming_exceptions:
print 'WARNING : parameter {0} not found, typo suspected.'.format(par)
# all the defaults for parameters that could not be set automatically should go here
if defaults.GetParam('target'):
self.SetI2DefPar(inp, 'EXPTYPE', defaults.GetParam('target'))
first_proc = defaults.processes[0] if defaults.processes[0].nick!='createfree' else defaults.processes[1]
if first_proc.inp.Get(has_solvent_content=True):
self.SetI2DefPar(inp, 'SOLVENT_CONTENT', first_proc.inp.Get(has_solvent_content=True).solvent_content)
self.SetI2DefPar(inp, 'MONOMERS_ASYM', first_proc.inp.Get(has_monomers_asym=True).monomers_asym)
if first_proc.inp.Get(has_residues_mon=True):
self.SetI2DefPar(inp, 'RESIDUES_MON', first_proc.inp.Get(has_residues_mon=True).residues_mon)
if first_proc.inp.Get('model',typ=('substr','partial+substr'),has_num_atoms=True):
#self.SetI2DefPar(inp, 'NUMBER_SUBSTRUCTURE', int(first_proc.inp.Get('model',typ=('substr','partial+substr'),has_num_atoms=True).exp_num_atoms)/int(inp.MONOMERS_ASYM))
num_at=int(first_proc.inp.Get('model',typ=('substr','partial+substr'),has_num_atoms=True).exp_num_atoms)
if num_at>0:
self.SetI2DefPar(inp, 'NUMBER_SUBSTRUCTURE', num_at)
inp.NUMBER_SUBSTRUCTURE.setQualifier('allowUndefined', True )
# dealing with the obscure case of no S/SE atoms in the sequence (eg vapd)
else:
inp.NUMBER_SUBSTRUCTURE.setQualifier('allowUndefined', False )
if self.getWidget('NUMBER_SUBSTRUCTURE'):
self.getWidget('NUMBER_SUBSTRUCTURE').validate()
#if defaults.GetProcess('substrdet') and defaults.GetProcess('substrdet').GetProg().IsKey('dsul'):
# self.SetI2DefPar(inp, 'SUBSTRDET_NUM_DSUL', int(defaults.GetProcess('substrdet').GetProg('shelxd').GetKey('dsul')) )
if not ctrl.USE_COMB.isSet():
ctrl.USE_COMB.set( True )
if not ctrl.MB_PROGRAM.isSet() and self.basepipe.ToggleModelBuilding():
if ctrl.USE_COMB:
# it can happen that the program default is not assigned if eg cell exists but no spg
if defaults.GetProcess('comb_phdmmb').GetProcess('mb') and defaults.GetProcess('comb_phdmmb').GetProcess('mb').GetProg(supported=True):
self.SetI2DefPar(ctrl, 'MB_PROGRAM', defaults.GetProcess('comb_phdmmb').GetProcess('mb').GetProg(supported=True).nick)
elif defaults.GetProcess('mbref'): # ie assuming mbref
if defaults.GetProcess('mbref').GetProcess('mb') and defaults.GetProcess('mbref').GetProcess('mb').GetProg(supported=True):
self.SetI2DefPar(ctrl, 'MB_PROGRAM', defaults.GetProcess('mbref').GetProcess('mb').GetProg(supported=True).nick)
# shelx MIND second parameter needs to be "translated"
if defaults.GetProcess('substrdet') and defaults.GetProcess('substrdet').IsParam('min_dist_symm_atoms'):
self.SetI2DefPar(ctrl, 'SUBSTRDET_MIN_DIST_SYMM_ATOMS', True if defaults.GetProcess('substrdet').GetParam('min_dist_symm_atoms')<0.1 else False, validate_widget=True )
# the first MIND parameter will show up positive but inputted as negative in the script
if ctrl.SUBSTRDET_MIN_DIST_ATOMS.isSet() and ctrl.SUBSTRDET_MIN_DIST_ATOMS<0.0:
self.SetI2DefPar(ctrl, 'SUBSTRDET_MIN_DIST_ATOMS', abs(ctrl.SUBSTRDET_MIN_DIST_ATOMS), validate_widget=True )
def_inp = first_proc.inp
mod = first_proc.inp.Get('model',typ=('substr','partial+substr'),has_atomtypes=True)
xn_nat = [o.GetCrystalName() for o in def_inp.GetAll('fsigf',typ='average') if 'native' in o.custom or o.GetCrystalName()=='native']
xn = [o.GetCrystalName() for o in def_inp.GetAll('fsigf',typ='plus') if 'native' not in o.custom and o.GetCrystalName()!='native']
# guess about substr atoms in native
if inp.NATIVE and len(xn_nat)>0:
self.SetI2DefPar(inp, 'SUBSTR_ATOMS_NATIVE', bool(defaults.inp.Get('model',typ=('substr','partial+substr'),xname=xn_nat[0])), validate_widget=True )
# self.SetI2DefPar(inp, 'SUBSTR_ATOMS_NATIVE', defaults.GetProcess('phdmmb').GetParam('substr_in_native'), validate_widget=True )
dname_undef = mod.default_unknown if mod else 'Undefined'
for i in range(4):
si = str(i+1) if i else ''
sif = si+'_nonmtz' if inp.NON_MTZ else si
dn = getattr(inp,'DNAME'+si) if getattr(inp,'DNAME'+si) else dname_undef
if dn in defaults.d_rename:
dn = defaults.d_rename[dn]
if getattr(inp,'F_SIGFanom'+sif).fullPath.isSet() and getattr(inp,'F_SIGFanom'+sif).contentFlag.isSet():
if mod and inp.ATOM_TYPE.upper()==mod.GetAtomType() and not None in mod.Getfpfpp(mod.GetAtomType(),dn):
self.SetI2DefPar(inp, 'FPRIME'+si, '{0:.2f}'.format(mod.Getfpfpp(mod.GetAtomType(),dn)[0]) )
self.SetI2DefPar(inp, 'FDPRIME'+si, '{0:.2f}'.format(mod.Getfpfpp(mod.GetAtomType(),dn)[1]) )
if first_proc.inp.Get('fsigf',dname=dn,has_wavel=True):
self.SetI2DefPar(inp, 'WAVELENGTH'+si, first_proc.inp.Get('fsigf',dname=dn,has_wavel=True).wavel)
# assigning the F's to speed up the future defaults generation.
if def_inp.Get('fsigf',xname=xn[0],dname=dn,typ='plus',col='f'):
getattr(inp,'SAVED_FPMFILE'+si).set( def_inp.Get('fsigf',xname=xn[0],dname=dn,typ='plus',col='f').GetFileName() )
getattr(inp,'SAVED_FAVFILE'+si).set( def_inp.Get('fsigf',xname=xn[0],dname=dn,typ='average',col='f').GetFileName() )
getattr(inp,'SAVED_FPLUS'+si).set( def_inp.Get('fsigf',xname=xn[0],dname=dn,typ='plus',col='f').GetLabel('f') )
getattr(inp,'SAVED_SIGFPLUS'+si).set( def_inp.Get('fsigf',xname=xn[0],dname=dn,typ='plus',col='f').GetLabel('sigf') )
getattr(inp,'SAVED_FMIN'+si).set( def_inp.Get('fsigf',xname=xn[0],dname=dn,typ='minus',col='f').GetLabel('f') )
getattr(inp,'SAVED_SIGFMIN'+si).set( def_inp.Get('fsigf',xname=xn[0],dname=dn,typ='minus',col='f').GetLabel('sigf') )
getattr(inp,'SAVED_FAVER'+si).set( def_inp.Get('fsigf',xname=xn[0],dname=dn,typ='average',col='f').GetLabel('f') )
getattr(inp,'SAVED_SIGFAVER'+si).set( def_inp.Get('fsigf',xname=xn[0],dname=dn,typ='average',col='f').GetLabel('sigf') )
if not si and xn_nat and def_inp.Get('fsigf',xname=xn_nat[0],typ='average',col='f'):
getattr(inp,'SAVED_FAVFILE_NATIVE').set( def_inp.Get('fsigf',xname=xn_nat[0],typ='average',col='f').GetFileName() )
getattr(inp,'SAVED_FAVER_NATIVE').set( def_inp.Get('fsigf',xname=xn_nat[0],typ='average',col='f').GetLabel('f') )
getattr(inp,'SAVED_SIGFAVER_NATIVE').set(def_inp.Get('fsigf',xname=xn_nat[0],typ='average',col='f').GetLabel('sigf') )
# reassign DNAME
if mod and mod.Getfpfpp(mod.GetAtomType(),dn,return_guessed_dtype=True)[4]:
self.SetI2DefPar( inp,'DNAME'+si, mod.Getfpfpp(mod.GetAtomType(),dn,return_guessed_dtype=True)[4], validate_widget=True )
# assign cell & spacegroup
if inp.NON_MTZ:
asc,ass=False,False
for fsigf in def_inp.GetAll('fsigf',xname=xn[0]) if xn else [] + def_inp.GetAll('fsigf',xname=xn_nat[0]) if xn_nat else []:
if fsigf.cell:
for i,c in enumerate(('CELL_A','CELL_B','CELL_C','CELL_D','CELL_E','CELL_F')):
if not self.SetI2DefPar(inp,c,fsigf.cell[i], emulate=True):
break
else:
for i,c in enumerate(('CELL_A','CELL_B','CELL_C','CELL_D','CELL_E','CELL_F')):
self.SetI2DefPar(inp,c,format(float(fsigf.cell[i]),'.1f'), validate_widget=True)
asc=True
if fsigf.spgr:
self.SetI2DefPar(inp,'SPACEGROUP',fsigf.spgr, validate_widget=True)
ass=True
if asc and ass:
break
except Exception as e:
print "Exception caught when setting the defaults: {}".format(e)
print traceback.print_exc()
print "Defaults assigned."
self.ConnectDefaultGenTrig()
def setByUser(self, param=None):
if self.getcont('USER_'+param) is not None:
print 'Parameter {0} set by user'.format(param)
self.getcont('USER_'+param).set( True )
def taskValidity(self):
from core import CCP4ErrorHandling
rv = CCP4ErrorHandling.CErrorReport()
ctrl, inp = self.container.controlParameters, self.container.inputData
if not inp.NON_MTZ:
for i in range(4):
si = str(i+1) if i else ''
if (not si or getattr(inp,'MAD'+si)) and (not getattr(inp,'F_SIGFanom'+si).contentFlag.isSet() or \
getattr(inp,'F_SIGFanom'+si).contentFlag not in (0,1,2)):
rv.append(self.__class__,' Wrong input data F_SIGFanom\n',details='Input file {} does not contain anomalous (I+,I- or F+,F-) data.'.format(getattr(inp,'F_SIGFanom'+si).fullPath),stack=False)
rv[-1]['description']="No anomalous data inputted for F_SIGFanom{}.".format(si)
if inp.SUBSTRDET_NUM_DSUL.isSet() and inp.NUMBER_SUBSTRUCTURE and inp.SUBSTRDET_NUM_DSUL*2>inp.NUMBER_SUBSTRUCTURE:
rv.append(self.__class__,' Too many disulphides inputted\n',details='{} sulpher atoms may form at most {} disulphides, however, {} disulphides inputted.'.format(
inp.NUMBER_SUBSTRUCTURE,int(inp.NUMBER_SUBSTRUCTURE)/2,inp.SUBSTRDET_NUM_DSUL), stack=False)
rv[-1]['description']="Number of disulphides larger than number of sulphers divided by two."
if self.TASKNAME!='shelx' and (not inp.FPRIME or not inp.FDPRIME):
rv.append(self.__class__,' f\' or f\'\' not known\n',details='Anomalous scattering coefficients f\', f\'\' should be directly inputted especially if they are known from a fluorescence scan. Otherwise data type or wavelength input can be used to calculate their theoretical value.', stack=False)
rv[-1]['description']="Anomalous scattering coefficients are needed by Crank2."
if len(rv)>0:
self.job_started=False
return rv
# defining job_started so that DNAME etc is not cleared on i2 internal data file path changes etc
def fix(self):
self.job_started=True
from core import CCP4ErrorHandling
return CCP4ErrorHandling.CErrorReport()
def PrepCont(cont,name='crank2'):
# helper function preparing a new container from an existing one
from core import CCP4Container
from core import CCP4File
cont_new = CCP4Container.CContainer(name=name)
cont_new.__dict__['header'] = CCP4File.CI2XmlHeader()
cont_new.__dict__['header'].pluginName = 'crank2' #name
for ic in ('inputData','controlParameters'):
cont_new.addObject( getattr(cont,ic), reparent=True )
cont_new.controlParameters.INITIAL_DEFAULTS_GEN.set(True)
#cont_new.inputData.END_PIPELINE.set('ref')
cont_new.inputData.END_PIPELINE.set('building')
cont_new.inputData.SHELX_SEPAR.set(name=='shelx'), cont_new.inputData.SHELXCDE.set(name=='shelx')
return cont_new
def whatNext(jobId,childTaskName,childJobNumber,projectName):
from core import CCP4Modules
from core import CCP4Container
from core import CCP4File
whatnext = []
cont = CCP4Modules.PROJECTSMANAGER().getJobParams(jobId)
if cont.outputData.XYZOUT.isSet():
whatnext.extend(['coot_rebuild','prosmart_refmac'])
if cont.outputData.FPHOUT_HL.isSet():
whatnext.append(['buccaneer_build_refine_mr','$CCP4I2/pipelines/buccaneer_build_refine_mr/script/bucref_after_experimental.params.xml'])
whatnext.append('arp_warp_classic')
if not cont.outputData.XYZOUT.isSet():
whatnext.extend(['parrot'])
if str(cont.inputData.EXPTYPE)!='MAD' or not cont.outputData.XYZOUT.isSet():
jobdir = CCP4Modules.PROJECTSMANAGER().jobDirectory(jobId)
xml_new, xml_sh = os.path.join(jobdir,'i2_crank2_next.xml'), os.path.join(jobdir,'i2_shelx_next.xml')
if cont.outputData.XYZOUT_SUB_RES.isSet() and cont.outputData.XYZOUT_SUBSTR.isSet():
cont_sh=PrepCont(cont,'shelx')
cont_sh.inputData.XYZIN_SUB_RES.set( cont.outputData.XYZOUT_SUB_RES )
cont_sh.inputData.XYZIN_SUB.set( cont.outputData.XYZOUT_SUBSTR )
cont_sh.inputData.START_PIPELINE.set('phdmmb')
cont_sh.saveDataToXml(fileName=xml_sh)
whatnext.append(['shelx',xml_sh])
cont_new=PrepCont( CCP4Modules.PROJECTSMANAGER().getJobParams(jobId) )
cont_new.controlParameters.USE_COMB.set(True)
if cont.outputData.F_SIGFanom_OUT.isSet():
cont_new.inputData.F_SIGFanom.set( cont.outputData.F_SIGFanom_OUT )
if cont.outputData.XYZOUT_SUBSTR.isSet():
cont_new.inputData.XYZIN_SUB.set( cont.outputData.XYZOUT_SUBSTR )
cont_new.inputData.START_PIPELINE.set('refatompick')
if cont.outputData.FPHOUT_HL.isSet():
cont_new.inputData.INPUT_PHASES.set(True)
cont_new.inputData.FPHIN_HL.set( cont.outputData.FPHOUT_HL )
cont_new.inputData.START_PIPELINE.set('dmfull')
if cont.outputData.XYZOUT.isSet():
cont_new.inputData.INPUT_PARTIAL.set(True)
cont_new.inputData.XYZIN.set( cont.outputData.XYZOUT )
cont_new.inputData.START_PIPELINE.set('building')
if str(cont.inputData.EXPTYPE)!='MAD' or not cont.outputData.XYZOUT.isSet():
cont_new.saveDataToXml(fileName=xml_new)
whatnext.append(['crank2',xml_new])
#whatnext.append([cont_new.__dict__['header'].pluginName,xml_new])
return whatnext
def exportMtzColumnLabels(jobId=None,paramNameList=None,sourceInfoList=[]):
colLabels = { 'FPHOUT_HL':'FPHOUT_HL', 'FPHOUT_DIFF':'FPHOUT_DIFF', 'FPHOUT_2FOFC':'FPHOUT_2FOFC', 'FPHOUT_DIFFANOM':'FPHOUT_DIFFANOM' }
#print 'CTaskCrank2.exportMtzColumnLabel',jobId,paramNameList,sourceInfoList
from core import CCP4Modules
paramsFile = CCP4Modules.PROJECTSMANAGER().makeFileName(jobId = jobId,mode='PARAMS')
#print 'CTaskCrank2.exportMtzColumnLabel paramsFile',paramsFile
from core import CCP4Container
c = CCP4Container.CContainer()
c.loadDataFromXml(paramsFile)
ret = []
indx = 0
for paramName in paramNameList:
if paramName.startswith('F_SIGF'):
if paramName.startswith('F_SIGFanom'):
dParam = 'DNAME' + paramName[-1] if paramName[-1] in ['2','3','4'] else 'DNAME'
label = c.inputData.get(dParam).__str__() if c.inputData.get(dParam) else 'anom'
else:
label = 'native'
ret.append('crank_'+label)
elif colLabels.get(paramName,None) is not None:
ret.append('crank_'+colLabels[paramName])
else:
indx += 1
ret.append('crank_'+str(indx))
return ret