//  SolidsPack Version 8/14/07
//  SIMPLEXER: SIMPLEXER (version 4)
//
//  SIMPLEXER 
//  Driver for Simplexer Scripts

//==========================================
//  Modifications
//
//  3/06: Add mode to bypass GUI
//        Finally clear 'SIMPLEXER' from wexp after error
//  8/06:
//        Add queuing
//        Add logging
//        Add intermediate store
//==========================================

//==========================================
// Create paths to files we will need 
//==========================================

//Macros
    $macroPath = userdir + '/maclib/'
    $initSimplex = $macroPath + 'initSimplex.tcl'
    $pokeFOM = $macroPath + 'pokeFOM'
    $killFile = $macroPath + 'killFile'
    $setMacroState = $macroPath + 'setMacroState'
    $simplexOptions = $macroPath + 'simplexOptions.tcl'
    $Simplexer = $macroPath + 'Simplexer'
    $initQueue = $macroPath + 'initQueue.tcl'
    $testQueue = $macroPath + 'testQueue.tcl'
    $vnmrWish = '/vnmr/tcl/bin/vnmrWish'
//File paths   
    $thisExp = curexp
    $communFile = $thisExp +'/tempCommun'
    $simplexVarsFile = $thisExp + '/simplex_vars'
    $curparFile = $thisExp + '/curpar'
    $thisPseq = seqfil
    $conparFile = '/vnmr/conpar'
    $macroStateFile = $thisExp + '/macroState'
    $fomFile = $thisExp + '/fomMethod'
    $logFile = $thisExp + '/simplexLog'
    $resultsFile = $thisExp + '/simplexResult'
    $queueFile = $thisExp + '/queue'
    $queueStateFile = $thisExp + '/queueState'
// Commands       
    $cmdInitSimplex = $vnmrWish + ' ' + $initSimplex + ' ' + $thisExp + ' ' + $thisPseq
    $cmdSimplexOptions = $vnmrWish + ' ' + $simplexOptions + ' ' + $thisExp
    $cmdSimplexer = $vnmrWish + ' ' + $Simplexer + ' ' + $communFile
    $cmdPokeFOM = $vnmrWish + ' ' + $pokeFOM + ' ' + $communFile
    $cmdSetMacroState = $vnmrWish + ' ' + $setMacroState + ' ' + $macroStateFile
    $cmdKillFile = $vnmrWish + ' ' + $killFile
    $cmdInitQueue = $vnmrWish + ' ' + $initQueue + ' ' + $thisExp
    $cmdTestQueue = $vnmrWish + ' ' + $testQueue + ' ' + $thisExp
   
    werr = 'wexp = \' \' '
//
// Synchronize curpar with expt display
//      
    flush 
      
//=========================================
//  Determine Macro State at Call Time
//=========================================

    if ($# = 0)
    then
        $MACRO_STATE = 'START'
        shell($cmdKillFile, $queueFile)
        $ROW_IDX = 1  
        write('reset', $logFile)     
        shell($cmdInitSimplex)
        lookup('file',$simplexVarsFile)
        lookup('readline'):$errorStatus
        if $errorStatus = 'error'
        then
            wexp = ''
            write('line3','%s','Abort Message Received during Simplex Setup')
            return
        endif
        shell($cmdSimplexOptions)
    else
        $MACRO_STATE = $1
        if ($MACRO_STATE = 'FILE') 
        then
            shell($cmdKillFile, $queueFile)
            $MACRO_STATE = 'START'
            $AUTO_FILE = $2
            $ROW_IDX = 1
            write('reset', $logFile)
            $cmdSimplexOptions = $cmdSimplexOptions + ' '  + $AUTO_FILE
            shell($cmdSimplexOptions)   
        else
            if ($MACRO_STATE = 'QUEUE')
            then
                $MACRO_STATE = 'START'
                if $# = 2
                then
                    $QUEUE_FILE = $2
                    $cmdInitQueue = $cmdInitQueue + ' ' + $QUEUE_FILE
                    shell($cmdInitQueue)
                endif
                lookup('file',$queueStateFile)
                lookup('readline'):$queueStatus
                if ($queueStatus = 'running')
                then
                    lookup('readline'):$nextFile
                    write('line3','Beginning queued method %s',$nextFile)
                    $cmdSimplexOptions = $cmdSimplexOptions + ' '  + $nextFile
                    shell($cmdSimplexOptions)
                    $ROW_IDX = 1
                else
                    wexp = ''
                    write('line3','Error In Strarting Queue. Corrupt/Absent Queue File. Aborting')
                    return
                endif
            else    
                if ($MACRO_STATE = 'CONTINUE')
                then
                    lookup('file',$macroStateFile)
                    lookup('readline'):$nDim
                    lookup('readline'):$MACRO_STATE
                    lookup('readline'):$ROW_IDX
                else
                    write('line3','%s','Invalid MACRO_STATE in macro call! Aborting')
                    wexp = ' '
                    wbs = ''
                    wnt = ''
                    return
                endif
            endif
        endif
    endif
  
//=================================================      
// If in write mode then compute fom and write 
// it to tempCommun. 
//=================================================
 
    if (($MACRO_STATE = 'WRITE_SCAN') or ($MACRO_STATE = 'WRITE_ROW'))
    then
        nrecords($fomFile):$nLines
        lookup('file',$fomFile)
        lookup('readline'):$method

        if ($method = 'shimSum')
        then
            fid_display
            fidarea:$fom
            $fom = 100000.0/$fom
        endif
        
        if ($method = 'integral')
        then
            lookup('read'):$left
	    lookup('read'):$width
	    write('line3','%s %s',$left,$width)
            wft
            ph
            ds
            mark('reset')
            mark($left,$width):$ht,$area
            write('line3','%s %3.2f','area is ',$area)
            abs($area):$fom

            if ($fom < 0.0001)
            then
                $fom = 0.0001
            endif

            $fom = 100000.0/$fom
        endif
        
        if ($method = 'peakHeight')
        then
            lookup('read'):$left
	    lookup('read'):$width
	    write('line3','%s %3.2f %3.2f','cursor ',$left,$width)
            wft
            ph
            ds
	    mark('reset')
            mark($left,$width):$ht,$area
            write('line3','%s %d','peak height is ',$ht)
            abs($ht):$fom
            $fom = 1000.0/$fom
        endif    
            
        write('line3','%s %2.5f','fom = ',$fom)
    endif
    
    if ($MACRO_STATE = 'WRITE_SCAN')
    then
        shell($cmdPokeFOM,'ytry',$fom)
        write('file',$logFile,'%s %4.2f','fom \t',$fom)
        shell($cmdSimplexer)
    endif 
             
    if ($MACRO_STATE = 'WRITE_ROW')
    then
        shell($cmdPokeFOM,$ROW_IDX,$fom)
        write('file',$logFile,'%s %4.2f','fom ',$fom)
        if $ROW_IDX < ($nDim + 1)
        then
            $ROW_IDX = $ROW_IDX + 1
        else
            $ROW_IDX = 1
            shell($cmdSimplexer)
        endif
    endif
       
//==================================================
//  read simplex_vars for variable names and limits
//==================================================

    lookup('file',$simplexVarsFile)
    nrecords($simplexVarsFile):$nLines
    lookup('readline'):$fileType

    if ($fileType <> 'simplex_vars')
    then 
        write('line3','Error reading simplex_vars file. File type error')
        return
    endif
    
    $i = 1
    while ($i < $nLines)
    do
        lookup('read',4):$a,$b,$c,$d
        $var[$i] = $a 
        $junk = $b 
        $sMin[$i] = $c 
        $sMax[$i] = $d      
        $i = $i + 1
    endwhile
                
//==================================================
// Read tempCommun to get current parameter values
// and the state of the simplex optimization 
//=================================================
  
    lookup('file',$communFile)
    lookup('readline'):$vb

    if ($vb = 99)
    then
        write('line3','Abort called from Simplex: Leaving')
        wexp = ' '
        return
    endif
        
    lookup('readline'):$method
    lookup('readline'):$STATUS
        
    if ($STATUS = 'FAIL_NO_FILE')
    then 
        write('error','Simplex Error: No Comunication File Found')
        wexp = ' '
        return 
    endif
               
    if ($STATUS = 'MAX_ITER_REACHED')
    then    
    write('error','Simplex Error: Maximum iterations reached')
        wexp = ''
        wbs = ''
        wnt = '' 
        return 
    endif
        
    if ($STATUS = 'UNKNOWN_ERROR')
    then 
        write('error','Simplex Error: Unknown Error')
        wexp = ''
        wbs = ''
        wnt = '' 
        return
    endif
             
    lookup('readline'):$POSITION
    lookup('readline'):$nDim
    $m = $nDim + 1
    lookup('readline'):$nMaxIter
    lookup('readline'):$fTol
    lookup('readline'):$nCurrentIter
        
    $i = 1
    while ($i <= $m)
    do
        lookup('read'):$tmp
        $y[$i] = $tmp
        $i = $i + 1
    endwhile
         
    $iCount = 1
    $i = 1
    while ($i <= $m)
    do
        $j = 1
        while ($j <= $nDim)
        do
            lookup('read'):$tmp
            $p[$iCount] = $tmp
            $j = $j + 1
            $iCount = $iCount + 1
        endwhile
        $i = $i + 1
    endwhile
        
    $i = 1
    while ($i <= $nDim)
    do
        lookup('read'):$tmp
        $psum[$i] = $tmp
        $i = $i + 1
    endwhile

    $i = 1
    while ($i <= $nDim)
    do
        lookup('read'):$tmp
        $ptry[$i] = $tmp
        $i = $i + 1
    endwhile
        
//dispense with eol from previous read
        
    lookup('readline')
    lookup('readline'):$inhi
    lookup('readline'):$ihi
    lookup('readline'):$ilo
    lookup('readline'):$ytry
    lookup('readline'):$ysave            
   
    if ($STATUS = 'CONVERGED')
    then
        write('line3','%s','Converged')

        $i = 1
        while ($i <= $nDim)
        do
            $temp = $p[$i]
            $name = $var[$i]
            sin($temp):$st
            abs($st):$ast
            $parVal = $sMin[$i] + $ast*( $sMax[$i] - $sMin[$i] )
            setvalue($name,$parVal)
            write('file',$resultsFile,'%s %4.3f',$name,$parVal)
            $i = $i + 1
        endwhile

        shell($cmdKillFile, $communFile)
        shell($cmdKillFile, $macroStateFile)
        shell($cmdTestQueue)
        lookup('file',$queueStateFile)
        lookup('readline'):$queueStatus

        if ($queueStatus = 'running')
        then
            wexp = 'SIMPLEXER(`QUEUE`)'
            write('line3','%s','Moving to next method. Burn a scan first')
            au('wait')
            return
        else
            wexp = ''
            write('line3','Done')
            shell($cmdKillFile, $queueStateFile)
            shell($cmdKillFile, $simplexVarsFile)
            shell($cmdKillFile, $fomFile)
            shell($cmdKillFile, $queueFile)
            return
        endif
    endif
  
//===================================
//  Select figure of merit method
//  on the first pass
//===================================   

    if ($STATUS = 'INIT')
    then
        if ($method = 'shimSum')
        then
            write('reset',$fomFile)
            write('fileline',$fomFile,'%s',$method) 
        endif
    
        if (($method = 'integral') or ($method = 'peakHeight'))
        then
            $left = cr
            $width = delta
            write('reset',$fomFile)
            write('file',$fomFile,'%s',$method)
            write('file',$fomFile,'%3.1f %3.1f',$left,$width)
        endif   
    endif
    
//===============================================
// If STATUS == 'INIT'  or 'RECOMPUTE_ALL'
// we must perform nDim
// experiments and write the results
// Difference between the 2 status values is
// relevant in the Simplexer script, not here
//===============================================

    if (($STATUS = 'INIT') or ($STATUS = 'RECOMPUTE_ALL'))
    then
        write('line3','STATUS = %s',$STATUS)

        $i = 1
        $j = 1 + ($ROW_IDX - 1)*$nDim 
        while ($i <= $nDim)
        do
            $temp = $p[$j]
            $name = $var[$i]
            sin($temp):$st
            abs($st):$ast
            $parVal =  $sMin[$i] + $ast*( $sMax[$i] - $sMin[$i] ) 
            write('line3','%s %s %s %3.2f','Setting ',$name,' to ',$parVal) 
            write('file',$logFile,'%s %4.2f',$name, $parVal)
            setvalue($name,$parVal)
            $j = $j + 1
            $i = $i + 1
        endwhile

        shell($cmdSetMacroState,$nDim,'WRITE_ROW',$ROW_IDX)
        wexp = 'SIMPLEXER(`CONTINUE`)'
        wbs = ''
        wnt = '' 
        au('wait')
        return   
    endif

//==============================================
// In the case of a simple loop the next guess
// is contained in vector ptry
//============================================== 
   
    if ($STATUS = 'SINGLE_PASS')
    then
        $i = 1
        while ($i <= $nDim)
        do
            $temp = $ptry[$i]
            $name = $var[$i]
            sin($temp):$st
            abs($st):$ast
            $parVal = $sMin[$i] + $ast*( $sMax[$i] - $sMin[$i] )
            write('line3','%s %s %s %3.2f','Setting ',$name,' to ',$parVal)
            write('file',$logFile,'%s  %4.2f',$name, $parVal)
            setvalue($name,$parVal)
            $i = $i + 1
        endwhile

        shell($cmdSetMacroState,$nDim,'WRITE_SCAN',1)
        wexp = 'SIMPLEXER(`CONTINUE`)'
        wbs = ''
        wnt = ''
        au('wait')
        return
    endif
   
    write('error','Error in SIMPLEXER. Unknown STATUS. Aborting')
    wexp = ''
    return
