
"""
     pipelines/refmac_ii2/Crefmac.py: CCP4 GUI Project
     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.
"""

"""
     Andrey Lebedev September 2011 - refmac_martin gui
     Liz Potterton Aug 2012 - convert for MTZ ADO's demo
     Liz Potterton Oct 2012 - Moved mini-MTZ version to refmac_martin
"""

from PyQt4 import QtGui,QtCore
import CCP4TaskWidget
import CCP4Widgets

def whatNext(jobId=None,childTaskName=None,childJobNumber=None,projectName=None):
    import os
    from lxml import etree
    import CCP4Modules, CCP4Utils, CCP4File, CCP4Container, CCP4Data, CCP4PluginScript
    jobStatus = CCP4Modules.PROJECTSMANAGER().db().getJobInfo(jobId,'status')
    if jobStatus == 'Unsatisfactory':
        returnList = ['LidiaAcedrg', 'prosmart_refmac']
    else:
        returnList = ['prosmart_refmac', 'coot_rebuild', 'buccaneer_build_refine_mr']
    return returnList

class Cprosmart_refmac(CCP4TaskWidget.CTaskWidget):

  TASKTITLE='Refinement - REFMAC5'
  SHORTTASKTITLE='REFMAC5'
  DESCRIPTION='Refine (Refmac5) with optional restraints (Prosmart)'
  TASKNAME = 'prosmart_refmac'
  TASKLABEL = 'refmac'
  TASKVERSION = 0.0
  TASKMODULE = 'refinement'
  MGDISPLAYFILES = ['XYZOUT','FPHIOUT','DIFFPHIOUT']
  AUTOPOPULATEINPUT = True
  RANK=1

  def __init__(self,parent):
    CCP4TaskWidget.CTaskWidget.__init__(self,parent)
      
  def ToggleWeightAuto(self):
    return str(self.container.controlParameters.WEIGHT_OPT) == 'MANUAL'
          
  def ToggleTLS(self):
    return self.container.inputData.TLSIN.isSet()
  def ToggleTLSNot(self):
    return not self.container.inputData.TLSIN.isSet()
  def ToggleTLSUsed(self):
    return self.container.inputData.TLSIN.isSet() or self.container.controlParameters.AUTOTLS
  def ToggleTLSNotUsed(self):
    return not self.container.inputData.TLSIN.isSet() and not self.container.controlParameters.AUTOTLS

  def drawContents(self):

    self.setProgramHelpFile('refmac')

    indent = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
    
    #-  --------------------          --------------------          --------------------
    
    folder = self.openFolder(folderFunction='inputData',title='Input Data')
    #self.createLine( [ 'advice',' '] )
    self.createLine( [ 'subtitle', 'Main inputs' ])
    self.openSubFrame(frame=[True])
    self.createLine( [ 'widget', '-browseDb', True, 'XYZIN' ] )
    self.createLine( [ 'widget', '-browseDb', True, 'F_SIGF' ])
    self.createLine( [ 'label','Use anomalous data for ', 'widget', 'USEANOMALOUSFOR', 'stretch', 'label', 'Wavelength', 'widget', 'WAVELENGTH'],toggleFunction=[self.anomalousAvailable,['F_SIGF']])
    if self.isEditable():
        self.connect(self.container.inputData.F_SIGF, QtCore.SIGNAL('dataChanged'), self.F_SIGFChanged)
        if not self.container.controlParameters.WAVELENGTH.isSet(): self.getWavelength()
    self.createLine( [ 'widget', '-browseDb', True, 'FREERFLAG' ] )
    self.closeSubFrame()
    #self.createLine( [ 'advice',' '] )
    self.createLine( [ 'subtitle', 'Optional additional inputs' ])
    self.openSubFrame(frame=[True])
    self.createLine( [ 'widget', '-browseDb', True, 'ABCD' ] )
    self.createLine( [ 'widget', '-browseDb', True, 'TLSIN'] )
    self.createLine( [ 'widget', '-browseDb', True, 'DICT' ] )
    self.createLine( [ 'widget', '-browseDb', True, 'REFERENCE_MODEL' ] )
    self.closeSubFrame()
    
    #-   --------------------          --------------------          --------------------
    
    folder = self.openFolder(folderFunction='controlParameters',title='Options', drawFolder=self.drawControlParameters)
    
    #-   --------------------          --------------------          --------------------
    
    folder = self.openFolder(folderFunction='controlParameters',title='Advanced Options', drawFolder=self.drawAdvancedOptions)
      
#-  --------------------          --------------------          --------------------

  def drawControlParameters( self ):
      
    indent = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
      
    self.createLine( [ 'subtitle', 'Main refinement options'] )
    self.openSubFrame(frame=[True])
    self.createLine( [ 'label', 'Number of refinement cycles:', 'stretch', 'widget', 'NCYCLES' ] )
    
    auto_weight = self.createLine( [ 'label', 'Weight restaints versus experimental data using', 'widget', 'WEIGHT_OPT', 'label', 'weight'] )
    self.createLine( [ 'label', ':', 'widget', 'WEIGHT' ], toggleFunction=[self.ToggleWeightAuto, ['WEIGHT_OPT']], appendLine=auto_weight )
    
    use_twin = self.createLine( [ 'widget', 'USE_TWIN', 'label', 'Crystal is twinned' ] )
    self.createLine( [ 'label', 'Perform twin refinement using observed', 'widget', 'TWIN_TYPE' ], toggle = ['USE_TWIN', 'open', [ True ] ],appendLine=use_twin )
         
    #- OLD KEYWORD: self.createLine( [ 'label', 'Set of hydrogen atoms to model', 'stretch', 'widget', 'HYDROGENS' ] )
    use_hydr = self.createLine( [ 'widget', 'HYDR_USE', 'label', 'Use hydrogens during refinement'] )
    self.createLine( [ 'widget', 'HYDR_ALL' ], toggle = ['HYDR_USE', 'open', [ True ] ], appendLine=use_hydr )
                        
    self.closeSubFrame()
    
    
    self.createLine( [ 'subtitle', 'Parameters' ] )
    self.openSubFrame(frame=[True])
    
    self.createLine( [ 'label','Use','widget', 'B_REFINEMENT_MODE', 'label','B-factors'] )
    
    self.createLine( [ 'label', 'TLS input file has been provided. Number of TLS refinement cycles:', 'stretch', 'widget', 'NTLSCYCLES' ], toggleFunction=[self.ToggleTLS, ['TLSIN']])
    tls_cycles = self.createLine( [ 'widget', 'AUTOTLS', 'label', 'Use TLS parameters' ], toggleFunction=[self.ToggleTLSNot, ['TLSIN']])
    self.createLine( [ 'label', 'Number of TLS refinement cycles:', 'widget', 'NTLSCYCLES_AUTO' ], toggleFunction=[self.ToggleTLSUsed, ['TLSIN','AUTOTLS']], appendLine=tls_cycles)
    reset_bfac_tls = self.createLine( [ 'label', indent, 'widget', 'TLSBFACSETUSE', 'label', 'Reset all B-factors at start' ], toggleFunction=[self.ToggleTLSUsed, ['TLSIN','AUTOTLS']])
    self.createLine( [ 'label', '&nbsp;to fixed value:', 'widget', 'TLSBFACSET' ], toggle = ['TLSBFACSETUSE', 'open', [ True ] ], appendLine=reset_bfac_tls )
    self.closeSubFrame()
    
    
    self.createLine( [ 'subtitle', 'Restraints' ] )
    self.openSubFrame(frame=[True])
    
    #- OLD KEYWORD: self.createLine( [ 'widget', 'USE_LOCAL_SYMMETRY','label', 'Use local symmetry' ] )
    self.createLine( [ 'widget', 'USE_NCS', 'label', 'Use non-crystallographic symmetry (NCS) restraints' ] )
    self.createLine( [ 'label', indent+'Use', 'widget', 'NCS_TYPE', 'label', 'NCS restraints, generated', 'widget', 'NCS_AUTO' ], toggle = ['USE_NCS', 'open', [ True ] ] )
    
    use_jellybody = self.createLine( [ 'widget', 'USE_JELLY', 'label', 'Use jelly-body restraints' ] )
    self.createLine( [ 'label', '&nbsp;with sigma:', 'widget', 'JELLY_SIGMA', 'label', 'and max distance:', 'widget', 'JELLY_DIST' ], toggle = ['USE_JELLY', 'open', [ True ] ], appendLine=use_jellybody)
    self.closeSubFrame()
    
    self.createLine( [ 'subtitle', 'Scaling' ] )
    self.openSubFrame(frame=[True])
    
    self.createLine( [ 'widget', 'SCALETYPE', 'label', 'Specify scaling model' ] )
    self.closeSubFrame()
    
    self.createLine( [ 'subtitle', 'Output options'])
    self.openSubFrame(frame=[True])
    
    self.createLine( [ 'widget', 'MAP_SHARP', 'label', 'Perform map sharpening when calculating maps' ] )
    use_mapsharp = self.createLine( [ 'label', indent, 'widget', 'MAP_SHARP_CUSTOM', 'label', 'Use custom sharpening parameter (B-factor)' ], toggle = ['MAP_SHARP', 'open', [ True ] ] )
    self.createLine( [ 'label', ':', 'widget', 'BSHARP' ], toggle = ['MAP_SHARP_CUSTOM', 'open', [ True ] ], appendLine=use_mapsharp)
    self.closeSubFrame()


  def drawAdvancedOptions( self ):
    indent = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
    #- REMOVED: self.createLine( [ 'label','Exit if new ligand encountered','stretch','widget', 'MAKE_NEW_LIGAND_EXIT'] )
    
    #- OLD KEYWORD: self.createLine( [ 'label', 'Resolution limits', 'stretch', 'widget', 'RESOLUTION' ] ) 
    custom_res = self.createLine( [ 'widget', 'RES_CUSTOM', 'label', 'Use custom resolution limits' ] )
    self.createLine( [ 'label', indent+indent+'min:', 'widget', 'RES_MIN', 'label', ' max:', 'widget', 'RES_MAX' ], toggle = ['RES_CUSTOM', 'open', [ True ] ], appendLine=custom_res )
    
    reset_bfac = self.createLine( [ 'widget', 'BFACSETUSE', 'label', 'Reset all B-factors at start' ], toggleFunction=[self.ToggleTLSNotUsed, ['TLSIN','AUTOTLS']])
    self.createLine( [ 'label', '&nbsp;to fixed value:', 'widget', 'BFACSET' ], toggle = ['BFACSETUSE', 'open', [ True ] ], appendLine=reset_bfac )
    
    self.createLine( [ 'widget', 'TLSOUT_ADDU', 'label', 'Add TLS contribution to output B-factors (only for analysis and deposition)' ] )
    
    self.createLine( [ 'widget', 'OPTIMISE_WEIGHT', 'label', 'Execute multiple refinement runs in order to optimise X-ray/geometry weight' ] )
    
    self.createLine( [ 'widget', '-guiMode','multiLine','EXTRAREFMACKEYWORDS' ] )

  def anomalousAvailable(self):
    if not self.container.inputData.F_SIGF.isSet(): return False
    if not self.isEditable(): return True
    #Peak to see if we can make F+/F-
    self.container.inputData.F_SIGF.setContentFlag(reset=True)
    canConvertString, toType = self.container.inputData.F_SIGF.conversion(2)
    print 'Can convert ?',self.container.inputData.F_SIGF.contentFlag, canConvertString, toType
    self.validate()
    if canConvertString == 'no':
        self.container.controlParameters.USEANOMALOUSFOR.set('NOTHING')
        return False
    else:
        return True

  def F_SIGFChanged(self):
    self.getWavelength()
    self.setTwinMode()
  
  def setTwinMode(self):
    if self.container.inputData.F_SIGF.isSet():
        columnLabelsInFile = [column.columnLabel.__str__() for column in self.container.inputData.F_SIGF.fileContent.listOfColumns]
        if not 'I' in columnLabelsInFile and not 'Iplus' in columnLabelsInFile:
            self.container.controlParameters.TWIN_TYPE.setQualifiers({'enumerators':['F'],'menuText':['SF Amplitudes (F)']})
            self.container.controlParameters.TWIN_TYPE.set('F')
        else:
            self.container.controlParameters.TWIN_TYPE.setQualifiers({'enumerators':['I','F'],'menuText':['Intensities (I)','SF Amplitudes (F)']})
            self.container.controlParameters.TWIN_TYPE.set('I')
        try:
            self.getWidget('TWIN_TYPE').populateComboBox(self.container.controlParameters.TWIN_TYPE)
            self.getWidget('TWIN_TYPE').updateViewFromModel()
        except:
            pass
        self.validate()
  
  def getWavelength(self):
    if self.container.inputData.F_SIGF.isSet():
        wavelengths = self.container.inputData.F_SIGF.fileContent.getListOfWavelengths()
        if len(wavelengths)>0: self.container.controlParameters.WAVELENGTH = round(wavelengths[-1],3)
        try:
            self.getWidget('WAVELENGTH').updateViewFromModel()
        except:
            print  'prosmart_refmac - WAVELENGTH widget  updateViewFromModel failed'

