#!/bin/sh  
# \
exec oagwish "$0" "$@"

set auto_path [linsert $auto_path 0  /usr/local/oag/apps/lib/$env(HOST_ARCH)]
set auto_path [linsert $auto_path 0 /usr/local/oag/lib_patch/$env(HOST_ARCH)]
set auto_path [linsert $auto_path 0 /home/helios/CARWAR/oag/apps/src/pslib]

APSDebugPath

set CVSRevisionAuthor "\$Revision: 1.1 $ \$Author: carwar $"

set systemsImplemented {psts}

set usage "usage: APSCalibratePSTS -system \{ $systemsImplemented \}"
set args $argv
set system psts

if {[APSStrictParseArguments {system}] || [lsearch -exact $systemsImplemented $system]==-1} {
    APSAlertBox [APSUniqueName .] -errorMessage "$usage"
    exit 1
}

set PSToCalibrate ""

set apsDCPSCalMainDir /home/helios/oagData/DCPSCalibration
#set apsDCPSCalMainDir /home/oxygen/PSGROUP/scratch

set pvRootList { PS:S:C1 PS:S:SQ2 PS:S:S3 PS:S:Q4 PS:S:C5 PS:S:MT6 PS:S:S7 PS:S:Q8 }
set ETSRootList { PS-SR-CORR- PS-SR-SKEW- PS-SR-TRIM- PS-SR-QUAD- PS-SR-SEXT- }
set DRVHList { 150  10  60 200 460 }
set DRVLList {-150 -10 -60   0   0 }
set slot1List { PS-SR-CORR- }
set slot2List { PS-SR-SKEW- }
set slot3List { PS-SR-SEXT- }
set slot4List { PS-SR-QUAD- }
set slot5List { PS-SR-CORR- }
set slot6List { PS-SR-TRIM- }
set slot7List { PS-SR-SEXT- }
set slot8List { PS-SR-QUAD- }
set selectedList ""
set slotsInUseList ""
set ETSNumberList ""

proc APSPSTestStandReturnSelectedDCPS {} {
    global pvRootList selectedList slotsInUseList ETSNumberList
    set selectedList ""
    set slotsInUseList ""
    set ETSNumberList ""
    
    for {set i 0} {$i < 8} {incr i} {
	set slot [expr $i + 1]
	global [subst slot${slot}Selection] [subst slot${slot}ETSNumber]
	if {[subst \$slot${slot}ETSNumber] != ""} {
	    lappend selectedList [lindex $pvRootList $i]
	    lappend slotsInUseList $slot
	    lappend ETSNumberList [subst \$slot${slot}ETSNumber]
	}
    }
    
    if {[APSPSTestStandValidateETSNumber] != 1} {
	set selectedList ""
	set slotsInUseList ""
	set ETSNumberList ""
    }
    return $selectedList
    
}

proc APSReturnSelectedDCPS {args} {
    set system psts
    APSStrictParseArguments {system}
    switch $system {
        psts {
            return [APSPSTestStandReturnSelectedDCPS]
        }
    }
    
}

proc APSPutETSNumbersInDataFiles {args} {
    global selectedList ETSNumberList status
    APSStrictParseArguments {filename}
    
    set parStr ""
    if {[llength $ETSNumberList] == [llength $selectedList]} {
	for {set i 0} {$i < [llength $selectedList]} {incr i} {
	    lappend parStr "-editnames=column,[lindex $selectedList $i]*,%/[lindex $selectedList $i]/[lindex $ETSNumberList $i]/"
	}
	catch [eval exec "sddsconvert $filename -nowarnings [join $parStr]"] status
	catch [exec /bin/rm ${filename}~] status
    }
    
    set parStr ""
    if {[llength $ETSNumberList] == [llength $selectedList]} {
	for {set i 0} {$i < [llength $selectedList]} {incr i} {
	    lappend parStr "-reedit=column,PSName,%/[lindex $selectedList $i]/[lindex $ETSNumberList $i]/"
	}
	if [catch {eval exec "sddsprocess ${filename}.calRec -nowarnings [join $parStr]"} result ] {
	    set status "$result"; update
	}
	if [catch {exec /bin/rm ${filename}.calRec~} result ] {
	    set status "$result"; update
	}
    }
    
}

proc MakeCalibrationRun {} {
    global status system dataCollectionSetpoints percentOfRange
    global outputFile
    
    if {[APSQueryToProceed -message "Warning: calibrations can only be performed from the EAA PS Test Cage"] != 1} {
	set status "nothing done"
	return
    }
    
    set PSList [APSReturnSelectedDCPS -system $system]
    
    if {[llength $PSList] != 0} {
	APSWritePSTestStandHiLoLimits
    }

    RunCalibration -system $system -PSList $PSList \
	-dataPoints $dataCollectionSetpoints -percentOfRange $percentOfRange

    if {[info exists outputFile] && [file exists $outputFile]} {
	APSPutETSNumbersInDataFiles -filename $outputFile
    }
}

proc DisplayChosenDetails {} {
    global ETSNumberList system

    APSReturnSelectedDCPS -system $system
    DisplayCalibrationDetails -system $system -PSList $ETSNumberList

}

proc DisplayCalibrationHistory {} {
    global status apsDCPSCalMainDir system
    set tmpFile /tmp/[APSTmpString]

    set files [lsort -decreasing [glob -nocomplain ${apsDCPSCalMainDir}/${system}/CalData-????-???-????-??????.proc]]

    if [catch {eval exec sddscombine [join $files " "] -pipe=out \
	| sddsprocess -pipe -print=col,CalFile,%s,Filename \
	    -print=col,CalibrationDate,%s,TimeStamp \
	| sddscombine -pipe -merge \
	| sddsprocess -pipe=in ${tmpFile} "-reedit=col,CalFile,10Z/%/.proc//" } result] {
	    set status "$result"; update
    }
    
    if [catch {exec sddssort $tmpFile -pip=out -col=PSName,inc -col=CalFile,dec \
		| sddsprintout -pipe=in ${tmpFile}.2 \
		-format=double=%10.6f \
                "-title=History of all calibrations sorted by ETS number" \
		"-column=PSName,label=ETS Number " \
		-column=ASLO -column=AOFF "-column=CalibrationDate,label=Calibration Date   "  } result] {
        APSSetVarAndUpdate status "$result"
        return
    }
    APSFileDisplayWindow [APSUniqueName .] -fileName ${tmpFile}.2 -deleteOnClose 1 -width 80 \
      -height 20 -sddsExportableFile ${tmpFile}

    if [catch {exec sddssort $tmpFile -pip=out -col=CalFile,dec -col=PSName,inc \
		| sddsprintout -pipe=in ${tmpFile}.1 \
		-format=double=%10.6f -width=130 \
                "-title=History of all calibrations sorted by date of calibration" \
		"-column=CalibrationDate,label=Calibration Date         " \
		"-column=PSName,label=ETS Number " -column=ASLO -column=AOFF } result] {
        APSSetVarAndUpdate status "$result"
        return
    }
    APSFileDisplayWindow [APSUniqueName .] -fileName ${tmpFile}.1 -deleteOnClose 1 -width 80 \
      -height 20 -sddsExportableFile ${tmpFile}

}

proc APSPSTestStandSelectionFrame {widget args} {
    set parent ""
    set label "Converter Selection by Test Stand Slot"
    set variablePrefix S
    APSStrictParseArguments {parent label}

    APSFrame .title -parent $parent -label $label -height 1
    APSFrameGrid $widget -parent $parent -xList {left right} -yList {1 2 3 4} \
	-relief raised -bd 3 -packOption "-side top -anchor center"
    set w $parent$widget

    for {set slot 1} {$slot < 5} {incr slot} {
	global [subst slot${slot}List] [subst slot${slot}ETSNumber]
	APSLabeledEntry ${slot}ETSNumber -parent $w.left.${slot}.frame -textVariable [subst slot${slot}ETSNumber] \
	    -label "[string range [subst \$slot${slot}List] 7 10] ETS#" -width 15 -packOption "-side right"
    }
    for {set slot 5} {$slot < 9} {incr slot} {
	set loc [expr $slot - 4]
	global [subst slot${slot}List] [subst slot${slot}ETSNumber]
	APSLabeledEntry ${slot}ETSNumber -parent $w.right.${loc}.frame -textVariable [subst slot${slot}ETSNumber] \
	    -label "[string range [subst \$slot${slot}List] 7 10] ETS#" -width 15 -packOption "-side right"
    }

}

proc APSPSTestStandValidateETSNumber {args} {
    global status selectedList slotsInUseList ETSNumberList ETSRootList


    if {[llength $slotsInUseList] == 0} {
        set status "no converters selected"
        return 0
    }

    set go 1
    for {set i 0} {$i < [llength $slotsInUseList]} {incr i} {
	set ETSNumber [lindex $ETSNumberList $i]
	set slot [lindex $slotsInUseList $i]
	global [subst slot${slot}List]

	if {([string length $ETSNumber] != 15) || \
	    ([lsearch -glob  $ETSRootList [string range $ETSNumber 0 10]] == -1) || \
	    ([string match {0[0-9][0-9][0-9]} [string range $ETSNumber 11 15]] != 1) } {
	    set status "error: invalid ETS Number entered for slot $slot"
	    set go 0
	} else {
	    if {[lsearch -glob [subst \$slot${slot}List] [string range $ETSNumber 0 10]] == -1} {
		set status "error: slot $slot does not support converter type [string range $ETSNumber 6 9]"
		set go 0
	    }
	}
    }
    return $go
}

proc APSWritePSTestStandHiLoLimits {} {
    global status DRVHList DRVLList ETSRootList ETSNumberList selectedList

    set DRVHsave {150 200 200 460 200}
    set DRVLsave {-150 -200 -200 0 0}

    set HputList ""
    set LputList ""
    for {set i 0} {$i < [llength $ETSNumberList]} {incr i} {
	set ETSNumber [lindex $ETSNumberList $i]
	set typeIndex [lsearch -glob  $ETSRootList [string range $ETSNumber 0 10]]
	lappend HputList "[lindex $selectedList $i]:CurrentAO.DRVH=[lindex $DRVHList $typeIndex]"
	lappend LputList "[lindex $selectedList $i]:CurrentAO.DRVL=[lindex $DRVLList $typeIndex]"
    }
    set putCmd "cavput -pend=15 -list=[join $HputList ,],[join $LputList ,]"
    eval exec $putCmd

}

APSApplication . -name APSCalibratePSTS:$system -version $CVSRevisionAuthor \
  -overview "This tool allows calibration of DC power supplies for $system, in the sense of adjusting IOC constants to make the readback (CurrentAI) as close as possible to the setpoint (CurrentAO) over the full range of the supply."


set status "Working..."
APSScrolledStatus .status -parent .userFrame -textVariable status -width 65 \
  -height 5
update

switch $system {
    psts {
        APSPSTestStandSelectionFrame .pstssel -parent .userFrame
    }
}

set dataCollectionSetpoints 20
set percentOfRange 90
set fitSDLimit 0.1
set offsetLimit 100
set slopeDeviationLimit 0.01

APSFrameGrid .pile -parent .userFrame -yList {1 2 3 4}

APSLabeledEntry .points -parent .userFrame.pile.2 -label "Data collection setpoints: " \
    -textVariable dataCollectionSetpoints -contextHelp "Enter the number of setpoint values to use for calibration."
APSLabeledEntry .percent -parent .userFrame.pile.2 -label "Percent of range to use: " \
    -textVariable percentOfRange -contextHelp "Enter the percentage of the power supply range to use for the calibration.  Using a value too close to 100% will trip some supplies."
APSLabeledEntry .fitLimit -parent .userFrame.pile.2 -label "Limit on fit standard deviation: " \
    -textVariable fitSDLimit -contextHelp "Enter the limit (in Amps) of the standard deviation of the fit.  For supplies with SD's above this limit, no installation is done.  In addition, supplies that exceed this are not included in graphs."
APSLabeledEntry .offsetLimit -parent .userFrame.pile.2 -label "Limit on offset (A): " \
    -textVariable offsetLimit -contextHelp "Enter the limit (in Amps) on the offset (AOFF) for data that will be installed.  In addition, supplies that exceed this are not included in the graphs."
APSLabeledEntry .slopeDeviationLimit -parent .userFrame.pile.2 -label "Limit on slope deviation from unity: " \
    -textVariable slopeDeviationLimit -contextHelp "Enter the limit on the slope error (|1-ASLO|) for data that will be installed.  In addition, supplies that exceed this are not included in the graphs."

APSButton .run -parent .userFrame.pile.3 -text "Run calibration" \
  -command { MakeCalibrationRun } \
  -contextHelp "Runs calibration for the chosen power supplies." \
  -highlightColor red -highlight 1

APSButton .process -parent .userFrame.pile.4 -text "Process/display calibration" \
  -command {ProcessCalibrationChoice -system $system -SDLimit $fitSDLimit -offsetLimit $offsetLimit -slopeDeviationLimit $slopeDeviationLimit} \
  -contextHelp "Process and/or display calibration data previously acquired."
APSButton .displayChosen -parent .userFrame.pile.4 -text "Display chosen details" \
  -command { DisplayChosenDetails } \
  -contextHelp "Displays details from calibration scan on the power supplies selected above"

APSButton .displayHistory -parent .userFrame.pile.4 -text "Calibration history" \
  -command { DisplayCalibrationHistory } \
  -contextHelp "Display information about all calibration records for $system"

APSSetVarAndUpdate status "Ready."

