# $log:$

proc APSMpxLTPMatrixInfo {} {
    return "This procedure measures the LTP response matrix in the horizontal plane, calculates the inverse matrix, and gives the user a choice to install this inverse matrix as the matrix for the xLTP controllaw."
}

proc APSMpxLTPMatrix {args} {
    global status


# the final result (.def and inverse matrix file) go in the resultsDir
# the temporary results go the dataDir.
    set resultsDir /home/helios/oagData/controllaw/LTP/usingL5
    set dataDir $resultsDir/measurement
    set installName xLTP.matrix
    set beamline LTP
    set beamlineFile $dataDir/${beamline}.beamline
    set plane H
    set matrix R12
    set templateFile $dataDir/${beamline}:${plane}Template.exp
    set actuatorList {H1 H2 H4}
    set actuatorList [APSAffix $actuatorList -prefix ${beamline}:]
    set actuatorList [lappend actuatorList SledTiming]
    # default for filterColumns in procedure formMatrix is "*:*P*"
    set filterColumns "$beamline:P${plane}*"

    cd $dataDir

    # Setting up experiment parameters
    set halfRange 0.75
    set points 5
    set postChange 2
    set intermeasurement 1.0
    set average 5
    set checkResults 1
    set skipExperiments 0
    APSMpStep init -promptDialog APSMpxLTPMatrixInitDialog -vars {halfRange points postChange intermeasurement average checkResults skipExperiments}

    set paramString ""
    foreach param {halfRange points postChange intermeasurement average checkResults skipExperiments} {
        append paramString "$param=\"[set $param]\" "
    }
    catch {APSLogScriptAction \
             -procedure APSMpxLTPMatrix \
             -action initialize \
             -state ok \
             -parameters $paramString}

# this procedure establishes some default variables and arrays for parameters.
    set parameterList {PV halfRange points postChange intermeasurement average}
    APSMpRespMatrixSetParameterDefaults \
      -parameterList $parameterList \
      -halfRange $halfRange \
      -points $points \
      -postChange $postChange \
      -intermeasurement $intermeasurement \
      -average $average
    foreach actuator $actuatorList {
        if {[string match SledTiming $actuator]} {
            # this procedure must be preceded by APSMpRespMatrixSetParameterDefaults
            # in order for the arguments to be recognized.
            APSMpRespMatrixSetActuatorParameters \
              -actuator $actuator \
              -PV L5:TM:sledTrigAO \
              -halfRange 0.07
        } else {
            APSMpRespMatrixSetActuatorParameters \
              -actuator $actuator \
              -PV ${actuator}:CurrentAO 
        }
    }
    #  bad equipment to remove from lists
    set badActuators ""
    set badBpms ""

    # put pre-execution commands here
    # such as reseting the time-outs for the pulsed magnets.
    APSMpStep PreExecutionCommands
    set rate [exec cavget -list=LI:TM:gunTrigCountCC]
    exec cavput -list=LTP:PH -list=1,2,3,4 -list=:BPM.CAVG=$rate

    # take data
    APSMpStep SDDSExperimentCommands
    # send a list of one actuator at a time so that the data can be reviewed
    # and restarted at every step
    if {!$skipExperiments} {
        foreach actuator $actuatorList {
            APSMpRespMatrixDoExperiment -actuatorList $actuator -templateFile $templateFile
            catch {eval exec rm [glob -nocomplain *~]}
            if $checkResults {
                set goodData 0
                while {!$goodData} {
                    eval exec sddsplot -col=$actuator,(LTP:P*) $actuator.sdds \
                      -grap=sym,conn,sca=3 -sep &
                    if {[APSYesNoPopUp "Retake data? (wait for plot to appear)"]} {
                        APSMpRespMatrixSetActuatorParametersByDialog .dialog -actuator $actuator
                        APSMpRespMatrixDoExperiment -actuatorList $actuator \
                          -templateFile $templateFile
                    } else {
                        set goodData 1
                    }
                }
            }
        }
    }
    # put post-execution commands here
    APSMpStep PostExecutionCommands

    APSMpStep CombiningResults
    if {!$skipExperiments} {
        eval exec sddscombine [APSAffix $actuatorList -suffix .def] -pipe=output -merge -overWrite \
          | sddssort -pipe=input ${beamline}.${plane}.def -col=ControlName  -unique
        eval exec rm [APSAffix $actuatorList -suffix .def]
    }

    APSMpStep CalculatingSlopes -proc "APSMpRespMatrixCalcSlopes"
    APSMpRespMatrixCalcSlopes -actuatorList $actuatorList 

    APSMpStep FormingMatrix -proc "APSMpRespMatrixFormMatrix"
    APSMpRespMatrixFormMatrix -actuatorList $actuatorList -badBpms $badBpms -badActuators $badActuators \
      -outFile ${beamline}.${matrix} -beamlineFile $beamlineFile -filterColumns $filterColumns

    APSMpStep CalculatingInverse -proc "APSMpRespMatrixCalcInverse"
    APSMpRespMatrixCalcInverse -inFile ${beamline}.${matrix} -outFile ${beamline}.Inv${matrix} -minimum 0.01

    APSMpStep InstallMatrix -proc "APSMpRespMatrixInstallDialog"
    APSMpRespMatrixInstallDialog .install -fileName ${beamline}.Inv${matrix} \
      -installName $installName -installDir $resultsDir
    APSMpReturn ok
}


# Note: by convention, this procedure has only one argument. It provides the
#    parent frame into which you should pack all widgets.
proc    APSMpxLTPMatrixInitDialog {frame} {
  # Note: this dialog procedure has access only to those variables explicitly
  #    passed in via the -vars option of APSMpStep. You can access them here
  #    as elements of the following global array (which always has the same
  #    name as the machine procedure itself.
  global APSMpxLTPMatrix
  label $frame.label -text "Enter default values for sddsexperiment"
  pack $frame.label
  APSLabeledEntry .le1 -parent $frame -label "half range" -textVariable \
    APSMpxLTPMatrix(halfRange)
  APSLabeledEntry .le2 -parent $frame -label "no. points" -textVariable \
    APSMpxLTPMatrix(points)
  APSLabeledEntry .le3 -parent $frame -label "post change pause" -textVariable \
    APSMpxLTPMatrix(postChange)
  APSLabeledEntry .le4 -parent $frame -label "intermeasurement pause" -textVariable \
    APSMpxLTPMatrix(intermeasurement)
  APSLabeledEntry .le5 -parent $frame -label "no. average" -textVariable \
    APSMpxLTPMatrix(average)
  APSLabeledEntry .le6 -parent $frame -label "check results?" -textVariable \
    APSMpxLTPMatrix(checkResults)
  APSLabeledEntry .le7 -parent $frame -label "skip experiments?" -textVariable \
    APSMpxLTPMatrix(skipExperiments)
}

proc APSMpyLTPMatrixInfo {} {
    return "This procedure measures the LTP response matrix in the horizontal plane, calculates the inverse matrix, and gives the user a choice to install this inverse matrix as the matrix for the yLTP controllaw."
}

proc APSMpyLTPMatrix {args} {
    global status


# the final result (.def and inverse matrix file) go in the resultsDir
# the temporary results go the dataDir.
    set resultsDir /home/helios/oagData/controllaw/LTP/usingL5
    set dataDir $resultsDir/measurement
    set installName yLTP.matrix
    set beamline LTP
    set beamlineFile $dataDir/${beamline}.beamline
    set plane V
    set matrix R34
    set templateFile $dataDir/${beamline}:${plane}Template.exp
    set actuatorList {V1 V2 V3 V4}
    set actuatorList [APSAffix $actuatorList -prefix ${beamline}:]
    # default for filterColumns in procedure formMatrix is "*:*P*"
    set filterColumns "$beamline:P${plane}*"

    cd $dataDir

    # Setting up experiment parameters
    set halfRange 0.7
    set points 5
    set postChange 2
    set intermeasurement 1.0
    set average 5
    set checkResults 1
    set skipExperiments 0
    APSMpStep init -promptDialog APSMpyLTPMatrixInitDialog -vars {halfRange points postChange intermeasurement average checkResults skipExperiments}

    set paramString ""
    foreach param {halfRange points postChange intermeasurement average checkResults skipExperiments} {
        append paramString "$param=\"[set $param]\" "
    }
    catch {APSLogScriptAction \
             -procedure APSMpyLTPMatrix \
             -action initialize \
             -state ok \
             -parameters $paramString}

# this procedure establishes some default variables and arrays for parameters.
    set parameterList {PV halfRange points postChange intermeasurement average}
    APSMpRespMatrixSetParameterDefaults \
      -parameterList $parameterList \
      -halfRange $halfRange \
      -points $points \
      -postChange $postChange \
      -intermeasurement $intermeasurement \
      -average $average
    foreach actuator $actuatorList {
# this procedure must be preceded by APSMpRespMatrixSetParameterDefaults
# in order for the arguments to be recognized.
        APSMpRespMatrixSetActuatorParameters \
          -actuator $actuator \
          -PV ${actuator}:CurrentAO 
    }
    #  bad equipment to remove from lists
    set badActuators ""
    set badBpms ""

    # put pre-execution commands here
    # such as reseting the time-outs for the pulsed magnets.
    APSMpStep PreExecutionCommands
    set rate [exec cavget -list=LI:TM:gunTrigCountCC]
    exec cavput -list=LTP:PV -list=1,2,3,4 -list=:BPM.CAVG=$rate

    # take data
    APSMpStep SDDSExperimentCommands
    # send a list of one actuator at a time so that the data can be reviewed
    # and restarted at every step
    if {!$skipExperiments} {
        foreach actuator $actuatorList {
            APSMpRespMatrixDoExperiment -actuatorList $actuator -templateFile $templateFile
            catch {eval exec rm [glob -nocomplain *~]}
            if $checkResults {
                set goodData 0
                while {!$goodData} {
                    eval exec sddsplot -col=$actuator,(LTP:P*) $actuator.sdds \
                      -grap=sym,conn,sca=3 -sep &
                    if {[APSYesNoPopUp "Retake data? (wait for plot to appear)"]} {
                        APSMpRespMatrixSetActuatorParametersByDialog .dialog -actuator $actuator
                        APSMpRespMatrixDoExperiment -actuatorList $actuator \
                          -templateFile $templateFile
                    } else {
                        set goodData 1
                    }
                }
            }
        }
    }
    # put post-execution commands here
    APSMpStep PostExecutionCommands

    APSMpStep CombiningResults
    if {!$skipExperiments} {
        eval exec sddscombine [APSAffix $actuatorList -suffix .def] -pipe=output -merge -overWrite \
          | sddssort -pipe=input ${beamline}.${plane}.def -col=ControlName  -unique
        catch {eval exec rm [APSAffix $actuatorList -suffix .def]}
    }

    APSMpStep CalculatingSlopes -proc "APSMpRespMatrixCalcSlopes"
    APSMpRespMatrixCalcSlopes -actuatorList $actuatorList 

    APSMpStep FormingMatrix -proc "APSMpRespMatrixFormMatrix"
    APSMpRespMatrixFormMatrix -actuatorList $actuatorList -badBpms $badBpms -badActuators $badActuators \
      -outFile ${beamline}.${matrix} -beamlineFile $beamlineFile -filterColumns $filterColumns

    APSMpStep CalculatingInverse -proc "APSMpRespMatrixCalcInverse"
    APSMpRespMatrixCalcInverse -inFile ${beamline}.${matrix} -outFile ${beamline}.Inv${matrix} -minimum 0.01

    APSMpStep InstallMatrix -proc "APSMpRespMatrixInstallDialog"
    APSMpRespMatrixInstallDialog .install -fileName ${beamline}.Inv${matrix} \
      -installName $installName -installDir $resultsDir
    APSMpReturn ok
}


# Note: by convention, this procedure has only one argument. It provides the
#    parent frame into which you should pack all widgets.
proc    APSMpyLTPMatrixInitDialog {frame} {
  # Note: this dialog procedure has access only to those variables explicitly
  #    passed in via the -vars option of APSMpStep. You can access them here
  #    as elements of the following global array (which always has the same
  #    name as the machine procedure itself.
  global APSMpyLTPMatrix
  label $frame.label -text "Enter default values for sddsexperiment"
  pack $frame.label
  APSLabeledEntry .le1 -parent $frame -label "half range" -textVariable \
    APSMpyLTPMatrix(halfRange)
  APSLabeledEntry .le2 -parent $frame -label "no. points" -textVariable \
    APSMpyLTPMatrix(points)
  APSLabeledEntry .le3 -parent $frame -label "post change pause" -textVariable \
    APSMpyLTPMatrix(postChange)
  APSLabeledEntry .le4 -parent $frame -label "intermeasurement pause" -textVariable \
    APSMpyLTPMatrix(intermeasurement)
  APSLabeledEntry .le5 -parent $frame -label "no. average" -textVariable \
    APSMpyLTPMatrix(average)
  APSLabeledEntry .le6 -parent $frame -label "check results?" -textVariable \
    APSMpyLTPMatrix(checkResults)
  APSLabeledEntry .le7 -parent $frame -label "skip experiments?" -textVariable \
    APSMpyLTPMatrix(skipExperiments)
}

