#!/usr/bin/python
import os,sys
from process import process
import common
par=common.parameter


class phas(process):
  name="phasing and substructure refinement"
  short_name="phasing"
  supported_progs=["bp3","refmac"]
  supported_params = {}
  supported_params['target'] = par( desc='Experiment/refinement target', typ=str, cap=True )
  supported_params['cycles'] = par( desc='Number of substructure refinement cycles', typ=int )
  supported_params['catch_output'] = par( desc='Catch program output continously', typ=bool )

  def Init(self):
    self.tables, self.in_table = [], 0

  def TreatInOutPar(self, set_all_par=False):
    if not self.GetProg(supported=True):
      # consult this with Raj and change accordingly after proper bp3 plugin exists etc
      if self.GetVirtPar('target') in ('SAD', 'SIRAS'):
        self.AddProg('refmac')
      else:
        self.AddProg('bp3')
    if self.GetParam('catch_output') is False:
      self.Info('Continous log output disabled.')
    elif self.GetProg('refmac') or self.GetParam('catch_output') is True:
      self.GetProg(supported=True).interact_output=True
    process.TreatInOutPar(self,set_all_par)

  def UpdateInfo(self,line,popen=None):
    if self.in_table:
      self.tables[-1].append(line)
      if line.strip()=='$$':
        self.in_table += 1
      if self.in_table==4:
        self.in_table = 0
        self.tables[-1] = ''.join(self.tables[-1])+'\n'
        self.PrintActualLogGraph()
    else:
      fom_table_start=self.GetProg(supported=True).GetStatGrep('lg_fom', from_str=line)
      if fom_table_start:
        self.tables.append([line,])
        self.in_table = 1

  def PrintActualLogGraph(self, finished=False):
    if finished:
      result = "Mean figure of merit (all reflections) is {0}".format(self.GetProg().GetStat('fom'))
    if self.opened_loggraph:
      self.GetLogGraphHandle().seek(0,0)
      self.LGInfo(self.GetCCP4Header())
      self.LGInfo(self.GetLogGraphPrograms())
      for table in self.tables:
        self.LGInfo(table)
      if finished:
        self.LGInfo('\n$TEXT:Result: $$ Final result $$')
        self.LGInfo("{0}\n$$\n".format(result))
    if self.rv_report is not None:
      if finished:
        self.rv_report.Text('<BR><i><small>Result:</small></i>')
        self.rv_report.Text('&emsp;'+result)
        self.rv_report.Text("<BR><i><small>Output:</small></i>")
        self.rv_files = self.rv_report.DataFile(self.out.Get('model').GetFileName(), "xyz", "<small>Refined substructure and experimental map</small>")
        self.rv_files.DataFile(self.out.Get('mapcoef',typ='best').GetFileName(), "hkl:map", flush=True)

  def RunBody(self,*args,**kwargs):
    self.GetProg().Run()
    self.Info( "Mean phasing figure of merit (all reflections) is {0}".format(self.GetProg().GetStat('fom')) )
    self.PrintActualLogGraph(finished=True)

  def RunPostprocess(self,restore=True,*args,**kwargs):
    # a workaround for bp3 replacing the residue type (for example IOD always becomes I)
    # this can (and is better to) be removed after this is fixed in bp3
    if self.GetProg().nick=='bp3':
      fixsub=self.AddProcess('fixsubstrpdb',propagate_inp=False)
      fixsub.inp.Add(self.out.Get('model',typ='substr',filetype='pdb'))
      fixsub.AddProg('pdbcur')
      fixsub.GetProg().outfilename['pdb'] = "fixed_"+self.nick+".pdb"
      fixsub.Run()
      self.processes.remove(fixsub)
    process.RunPostprocess(self,restore,*args,**kwargs)
