#
# $Log: not supported by cvs2svn $
# Revision 1.22  2010/12/21 15:31:46  shang
# added -resendFinal option to sddscaramp to assort the setpoints.
#
# Revision 1.21  2010/12/16 21:41:31  shang
# removed the last step setpoint reassuring because it does not work for less than 100 percentage ramp, instead will put it
# into sddscaramp; for non-sddscaramp, the last step of setpoint assortion is added here.
#
# Revision 1.20  2010/11/16 17:42:10  shang
# fixed a variable name typo where filename should be fileName instead.
#
# Revision 1.19  2010/10/28 19:15:04  shang
# added restoring setpoints at the end of ramp to assort the setpoints.
#
# Revision 1.18  2005/10/02 15:05:51  shang
# added -nowarnings to sddsprocess for filtering numerical and non-numerical pvs,
# otherwise, it catches errors and return.
#
# Revision 1.17  2005/09/28 22:46:02  soliday
# If there are no rows in the file to be restored after striping it of
# numerical or non-numerical PVs it will now skip over the related restore
# step.
#
# Revision 1.16  2005/09/28 22:40:19  soliday
# Fixed another typo.
#
# Revision 1.15  2005/09/28 22:22:54  soliday
# Fixed typo.
#
# Revision 1.14  2005/09/28 21:58:10  soliday
# Modified APSRampToSnapshot so that the non-numerical PVs are set correctly.
#
# Revision 1.13  2004/06/08 16:24:09  emery
# Indented code. Replace the "exec rm" with file delete.
# Reformatted some catch statements for readability.
#
# Revision 1.12  2003/09/25 18:33:42  soliday
# Added blt package require command.
#
# Revision 1.11  2001/03/05 21:30:58  soliday
# Launch sddscaramp from blt::bgexec because it was locking up when started
# from APSExec.
#
# Revision 1.10  1999/07/28 13:22:09  borland
# Fixed problem with burtrb of tclcaget snapshots.
#
# Revision 1.9  1999/06/02 14:11:36  borland
# Now use sddscaramp exclusively.
#
# Revision 1.8  1999/02/15 18:40:13  borland
# Added prescaling option.
#
# Revision 1.7  1998/11/02 15:44:11  borland
# Defined statusCallback default as APSNoOp.
#
# Revision 1.6  1998/10/22 12:56:50  borland
# Set a value for global variable apsRampToSnapshotOutput.
#
# Revision 1.5  1998/10/21 22:02:28  borland
# Added ability to ramp using sddscaramp.
#
# Revision 1.4  1997/10/23 18:29:12  borland
# Added abort feature for ramping, plus defaults for pause and number of steps.
#
# Revision 1.3  1997/02/04 16:52:31  borland
# Added facility for doing partial ramps.
#
# Revision 1.2  1996/12/13 01:47:06  borland
# Added initialization dialog and logFile option.
#
# Revision 1.1  1996/12/13 00:36:51  borland
# First version.
#
#

set apsRampToSnapshotCancelled 0
set apsRampToSnapshotPause 1
set apsRampToSnapshotSteps 30
set apsRampToSnapshotPercentage 100
set apsRampToSnapshotAbort 0
set apsRampToSnapshotUseSddscaramp 1
set apsRampToSnapshotPrescaleFactor 1

proc APSRampToSnapshot {args} {
    if {![llength [info commands blt::bgexec]]} {
	package require BLT
    }

    set fileName ""
    set steps -1
    set pause -1
    set percentage 100
    set statusCallback APSNoOp
    set logFile ""
    set initDialog 0
    set sddscarampInhibit 0
    set prescaleFactor 1
    if {[APSStrictParseArguments {fileName steps pause statusCallback logFile initDialog \
                                    percentage sddscarampInhibit prescaleFactor}] \
          || ![string length $fileName]} {
        return -code error "APSRampToSnapshot: bad arguments"
    }

    global apsRampToSnapshotAbort
    set apsRampToSnapshotAbort 0

    if {![file exists $fileName]} {
        return -code error "APSRampToSnapshot: $fileName not found"
    }

    if {$initDialog} {
        set widget [APSUniqueName .]
        APSDialogBox $widget -name "Snapshot ramp dialog" \
          -okCommand "set apsRampToSnapshotCancelled 0" \
          -cancelCommand "set apsRampToSnapshotCancelled 1" \
          -contextHelp "Set parameters for ramping to snapshot." 
        set w $widget.userFrame
        global apsRampToSnapshotSteps apsRampToSnapshotPause apsRampToSnapshotCancelled
        global apsRampToSnapshotPercentage apsRampToSnapshotUseSddscaramp
        global apsRampToSnapshotPrescaleFactor
        APSLabeledEntry .le0 -parent $w \
          -label "Ramp steps" -textVariable apsRampToSnapshotSteps \
          -contextHelp "Enter the number of steps to take in ramping."
        APSLabeledEntry .le1 -parent $w \
          -label "Pause (sec): " -textVariable apsRampToSnapshotPause \
          -contextHelp "Enter the time in seconds to pause between points in the ramp."
        APSLabeledEntry .le2 -parent $w \
          -label "Percentage: " -textVariable apsRampToSnapshotPercentage \
          -contextHelp "Enter the time in seconds to pause between points in the ramp."
        APSLabeledEntry .prescale -parent $w \
          -label "Prescale factor: " \
          -textVariable apsRampToSnapshotPrescaleFactor \
          -contextHelp "Choose whether to scale the data by a factor prior to ramping.  This might be used, for example, to scale power supply setpoints to a different energy."
        APSEnableButton $widget.buttonRow.ok.button
        tkwait window $widget
        set steps $apsRampToSnapshotSteps
        set pause $apsRampToSnapshotPause
        set percentage $apsRampToSnapshotPercentage
        set sddscarampInhibit [expr {$apsRampToSnapshotUseSddscaramp?0:1}]
        set prescaleFactor $apsRampToSnapshotPrescaleFactor
        if {$apsRampToSnapshotCancelled} {
            return -code error "APSRampToSnapshot: cancelled."
        }
    }

    if {$steps<=0 || $pause<=0} {
        return -code error "APSRampToSnapshot: bad arguments (step and pause)"
    }

    if {[string length $statusCallback]} {
        eval $statusCallback {"Setting up for ramp..."}
    }

    if {[expr {($prescaleFactor-1)!=0}]} {
        set newFile /tmp/[APSTmpString]
        APSAddToTempFileList $newFile
        if [catch {APSScaleSnapshot -input $fileName -output $newFile \
                     -factor $prescaleFactor \
                 } result] {
            return -code error "APSRampToSnapshot: $result"
        }
        set fileName $newFile
    }

    if {$sddscarampInhibit} {
        set tmpRoot /tmp/[APSTmpString]
        APSAddToTempFileList $tmpRoot.orig $tmpRoot.log $tmpRoot.both $tmpRoot.burtwb
        if [catch {exec sddsprocess $fileName $tmpRoot.orig \
                     -numberTest=column,ValueString,strict \
                     -scan=column,FinalValue,ValueString,%lf \
                 } result] {
            return -code error "APSRampToSnapshot: $result"
        }
        
        if [catch {exec sddscasr -save $fileName -pipe=out -logFile=$logFile \
                     | sddsprocess -pipe -numberTest=column,ValueString,strict -scan=column,PresentValue,ValueString,%lf \
                     | sddsxref -pipe $tmpRoot.orig -take=FinalValue \
                     | sddsconvert -pipe -dele=column,ValueString -retain=parameter,SnapType \
                     | sddsprocess -pipe=in $tmpRoot.both -match=column,ControlName=,! \
                 } result] {
            return -code error "APSRampToSnapshot: $result"
        }
        catch {file delete -force $tmpRoot.orig}
        
        for {set step 1} {$step<=$steps} {incr step} {
            if {[string length $statusCallback]} {
                eval $statusCallback {"Doing ramp step $step..."}
            }
            set fraction [expr {($percentage/100.0)*(1.0*$step)/$steps}]
            if {[catch {exec sddsprocess $tmpRoot.both $tmpRoot.burtwb \
                          "-define=column,Value,PresentValue FinalValue PresentValue - $fraction * +" \
                          -print=column,ValueString,%21.15e,Value} result]} {
                catch {file delete -force $tmpRoot.both}
                return -code error "APSRampToSnapshot: $result"
            }
            if {$apsRampToSnapshotAbort} {
                return -code error "Ramping aborted after [expr {$step-1}] steps"
            }
            if {[catch {exec sddscasr -restore $tmpRoot.burtwb -logFile=$logFile} result] || \
                  [catch {file delete -force $tmpRoot.burtwb} result]} {
                if {[string length $statusCallback]} {
                    eval $statusCallback {"$result"}
                }
            }
            if {[string length $statusCallback]} {
                if {[string length $statusCallback]} {
                    eval $statusCallback {"Values sent, waiting $pause seconds."}
                }
            }
            if {[llength [info command after]]} {
                after [expr {int(1000*$pause)}]
            } else {
                exec sleep [expr {int($pause)}]
            }
        }
        #restore the setpoint after final ramp to assort the setpoints
        if [catch {exec sddscasr -restore $tmpRoot.burtwb -pendIO=100} result] {
            return -code error "APSRampToSnapshot: error in assorting setpoints: $result"
        }
    } else {
        eval $statusCallback {"Ramping..."}
        global apsRampToSnapshotOutput
        set apsRampToSnapshotOutput ""
        set newFile /tmp/[APSTmpString]
        APSAddToTempFileList ${newFile}1 ${newFile}2

        if {[catch {exec sddsprocess $fileName ${newFile}1 -match=column,IsNumerical=+y -nowarnings} result]} {
            return -code error "Unable to strip out non-numerical PVs before ramping"
        }
        if {[catch {exec sddsprocess $fileName ${newFile}2 -match=column,IsNumerical=+y,! -nowarnings} result]} {
            return -code error "Unable to strip out non-numerical PVs before ramping: $result"
        }
        if {[catch {exec sdds2stream -rows=bare ${newFile}1} rows]} {
            set rows 0
        }
        if {$rows != 0} {
            if [catch {blt::bgexec apsRampToSnapshotAbort \
                         -output apsRampToSnapshotOutput  \
                         sddscaramp -rampto=${newFile}1,pause=$pause,steps=$steps,percentage=$percentage -resendFinal \
                     } result] {
                return -code error "Ramping aborted: $result."
            }
        }
        if {[catch {exec sdds2stream -rows=bare ${newFile}2} rows]} {
            set rows 0
        }
        if {$rows != 0} {
            if {[catch {exec sddscasr ${newFile}2 -restore} result]} {
                return -code error "Problem restoring non-numerical PVs: $result"
            }
        }
        eval $statusCallback {"Ramping completed."}
        if {[llength $apsRampToSnapshotOutput]} {
            return -code error "APSRampToSnapshot: $apsRampToSnapshotOutput"
        }
    }
}
