#!/usr/bin/python
import os,sys
from program import program
import common
import math

class prasa(program):
  name="PRASA"
  binary="prasa"
  labelout_prefix="PRAS_"
  modif='-'
  always_merge=True
  stat={}
  stat['cc'] = common.stats(name='correlation coef. (all reflections mean)', 
    regexp=r"Normal end of trial \d+, final CC is (\S+)")
  stat['try'] = common.stats(name='try number', regexp=r"Normal end of trial (\d+), final CC is \S+")

  def Init(self):
    self.SetArg('stdin')

  def Interact_output(self, line, popen, empty):
    self.process.UpdateInfo(line,popen)
    # this is done here in order to make sure that the same solution is not checked multiple times
    #if empty and self.process.check_solution[0]:
    if self.process.check_solution[0]:
      #self.process.CheckExtraStopConditionsPrasa(self.process.score,self.process.trial,self,popen)
      self.process.CheckExtraStopConditionsPrasa(self.process.check_solution[1],self.process.check_solution[0],self,popen)
      self.process.check_solution=(0,0)


  def Stop(self,popen=None):
    with open('stop_prasa', 'w') as f:
      f.write('stop_prasa')


  def TreatInput(self):
    self.ea = self.inp.Get('fsigf',typ='ea',filetype='mtz', inp_cont=self.inp.Get('fsigf',typ='average',filetype='mtz',try_convert=False))
    if not self.ea:
      self.ea = self.inp.Get('fsigf',typ='fa',filetype='mtz', inp_cont=self.inp.Get('fsigf',typ='average',filetype='mtz',try_convert=False))
    if not self.ea:
      self.ea = self.inp.Get('fsigf',typ='delta-anom',filetype='mtz')
    if self.ea is None:
      common.Error('FA/EA values not inputted to {0}'.format(self.name))
    self.SetKey('mtzin', self.ea.GetFileName('mtz'))
    self.SetKey('colin-fo', self.ea.GetFullLabel('f','sigf'))
    # expected number of atoms from substr. object
    if self.inp.Get(has_num_atoms=True) and not self.process.GetParam('expected_num_atoms') and not self.GetKey('natoms'):
      self.SetKey('natoms', self.inp.Get(has_num_atoms=True).exp_num_atoms)
    # atom type
    self.subs_inp=self.inp.Get('model',typ='substr',has_atomtypes=True)
    if self.subs_inp:
      self.SetKey('atom', self.subs_inp.GetAtomType())

  def TreatParams(self):
    if self.process.GetVirtPar('num_trials') and not self.GetKey('ntrials'):
      self.SetKey('ntrials', self.process.GetVirtPar('num_trials'))
    if self.process.GetVirtPar('high_res_cutoff') and not self.GetKey('rescut'):
      self.SetKey('rescut', self.process.GetVirtPar('high_res_cutoff'))
    if self.process.GetParam('expected_num_atoms') and not self.GetKey('natoms'):
      self.SetKey('natoms', self.process.GetParam('expected_num_atoms'))
    program.TreatParams(self)

  def DefineOutput(self):
    #self.out.AddNew( 'mapcoef', self.nick+'.map', filetype='map', typ='anomalous', xname=self.ea.GetCrystalName(), dname=self.ea.GetDataName() )
    if self.subs_inp:
      subs_out=self.out.AddCopy(self.subs_inp)
      self.out.AddFileToChild( subs_out, self.nick+'.pdb', filetype='pdb' )
    else:
      self.out.AddNew( 'model', self.nick+'.pdb', filetype='pdb', typ='substr', xname=self.ea.GetCrystalName() )

  def TreatOutput(self):
    #self.SetKey( 'mapout', self.out.mapcoef[-1].GetFileName('map') )
    self.SetKey( 'pdbout', self.out.model[-1].GetFileName('pdb') )

  def GetTrialPdb(self,trial):
    # returns input trial's pdb name (incl. path) 
    # must be called after DefineOutput(), otherwise there is an error.
    return self.out.Get('model').GetFileName()+"_"+str(trial)
