#!/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)]

#
# $Log: not supported by cvs2svn $
# Revision 1.4  2011/05/09 15:10:08  shang
# replaced "exec replace" command by "exec replaceText".
#
# Revision 1.3  2006/05/16 20:58:04  soliday
# Replace SY:PS:phaseShifter1Ch0 PV with BRF:K5:PS1:Ch0 because of a PV name change.
#
# Revision 1.2  2002/01/21 19:42:45  sereno
# Added path to oag area containing the sddsexperiment template file for
# longitudinal correction.  N. Sereno
#
# Revision 1.1  2002/01/21 06:30:58  sereno
# Script to measure the booster longitudinal injection response.  Actuators
# used are the booster start ramp time and rf phase.  Readbacks are the
# B2C8P2 or B3C2P1 processed beam history real and imag parts of the FFT
# at the synchrotron frequency.  N. Sereno
#

APSDebugPath
set CVSRevisionAuthor "\$Author: shang $"

set dataDir .
set nToAverage 10
set bpm B2C8P2
set nPoints 10
set nToAverage 10
set postChangePause 5
set interMeasPause 1
set dataDir [APSGoToDailyDirectory]
APSApplication . -name boosterLongRespMeas
set status "Ready."
APSScrolledStatus .status -parent .userFrame -textVariable status -height 4 -width 60

APSLabeledEntry .output -parent .userFrame -label "Data Directory: " \
    -textVariable dataDir -width 60 -contextHelp "Sddsexperiment data directory."
APSButton .daily -parent .userFrame.output -text "daily" -size small -command "set dataDir [APSGoToDailyDirectory]"
APSLabeledEntry .bpm -parent .userFrame -label "BPM Selection: " \
    -textVariable bpm -contextHelp "BPM selection with beam history FFT waveform processing setup."
APSLabeledEntry .npt -parent .userFrame -label "Number of points: " \
    -textVariable nPoints -contextHelp "Sddsexperiment number of points."
APSLabeledEntry .pcp -parent .userFrame -label "Post-change pause (s): " \
    -textVariable postChangePause -contextHelp "Sddsexperiment post change pause in seconds."
APSLabeledEntry .nave -parent .userFrame -label "Number to average: " \
    -textVariable nToAverage -contextHelp "Sddsexperiment average number."
APSLabeledEntry .imp -parent .userFrame -label "Intermeasurement pause (s): " \
    -textVariable interMeasPause -contextHelp "Sddsexperiment intermeasurement pause in seconds."

APSButton .run -parent .userFrame -text "Run/Analyze/Plot" \
  -command "ChangeButtonState 0; \
    RunLongRespMatrixMeas -doRun 1 -doAnalyze 1 -doPlot 1; \
    ChangeButtonState 1" \
  -contextHelp "Button to run the experiment, analyze and plot the data."
APSButton .analyze -parent .userFrame -text "Analyze/Plot" \
  -command "ChangeButtonState 0; RunLongRespMatrixMeas -doRun 0 -doAnalyze 1 -doPlot 1; \
    ChangeButtonState 1" \
  -contextHelp "Button to analyze and plot the experimental data."
APSButton .display -parent .userFrame -text "Plot" \
  -command "ChangeButtonState 0; RunLongRespMatrixMeas -doRun 0 -doAnalyze 0 -doPlot 1; \
    ChangeButtonState 1" \
  -contextHelp "Button to plot the experimental data."

proc ChangeButtonState {state} {
    if $state {
        APSEnableButton .userFrame.run.button 
        APSEnableButton .userFrame.analyze.button
        APSEnableButton .userFrame.display.button
    } else {
        APSDisableButton .userFrame.run.button 
        APSDisableButton .userFrame.analyze.button
        APSDisableButton .userFrame.display.button
    }
}


proc RunLongRespMatrixMeas {args} {
    set doRun 0
    set doAnalyze 0
    set doPlot 0
    APSStrictParseArguments {doRun doAnalyze doPlot}

    global dataDir launchPhase runDone bpm
    global initialValue finalValue nToAverage nPoints postChangePause interMeasPause
    
    set runDone 0

    if $doRun {
        if [file exists ${dataDir}/longResponse.inv] {
            if [APSMultipleChoice [APSUniqueName .] \
                  -question "${dataDir}/longResponse.inv exists.  What do you want to do?" \
                  -labelList "Abort Overwrite" \
                  -returnList "1 0"] {
                return 
            }
        }

        set actuatorNameList {StartRampTime RF12Phase}
        set procAndDataFileList {StartRampTime.sdds RF12Phase.sdds longRespMeas.exp longRespMeas.exp~ longResponse.inv}
        catch {eval exec rm $procAndDataFileList}

        APSSetVarAndUpdate status "Measuring booster longitudinal response..."
        foreach actuatorName $actuatorNameList {
	    set outputFile [file join ${dataDir}/${actuatorName}.sdds]
	    if [file exist $outputFile] {
		if ![APSYesNoPopUp "${actuatorName}.sdds already exist, do you want to overwrite and repeat the experiment?"] {
		    APSSetVarAndUpdate status "skip $actuatorName experiment."
		    continue
		}
	    }
            APSSetVarAndUpdate status "Measuring response for ${actuatorName}..."
            if {![string compare $actuatorName StartRampTime]} {
                set initialValue -0.040
                set finalValue 0.040
                set actuator "It:Bs:StartRamp2BsIp.VAL"
            } else {
                set initialValue -35
                set finalValue 35
                set actuator "PAR:RF12:PhsShft2Ch2_3AO"
            }
            exec replaceText /home/helios/oagData/controllaw/BOOSTER-IRamp-132nm-425MeV-2Hz/longBooster/boosterLongRespMeasTemplate.exp longRespMeas.exp \
              -original=<bpm>,<nAve>,<initialValue>,<finalValue>,<postChangePause>,<interMeasPause>,<nPoints>,<actuator>,<actuatorName> \
              -replace=$bpm,$nToAverage,$initialValue,$finalValue,$postChangePause,$interMeasPause,$nPoints,$actuator,$actuatorName 
            APSExecLog [APSUniqueName .] -unixCommand \
              "sddsexperiment longRespMeas.exp $outputFile -verbose -summar " \
              -cancelCallback "set runDone 2" \
              -abortCallback "set runDone 2" \
              -callback "set runDone 1" -width 80 
            tkwait variable runDone
            if $runDone!=1 {
                APSSetVarAndUpdate status "Run cancelled"
                return
            }
        }
        APSSetVarAndUpdate status "Done measuring booster longitudinal response."
    }

    if $doAnalyze {
        set actuatorNameList {StartRampTime RF12Phase}
        set actuatorSlopeList ""
        APSSetVarAndUpdate status "Analyzing booster longitudinal response data..."
        foreach actuatorName $actuatorNameList {
            set outputFile [file join ${dataDir}/ ${actuatorName}.sdds]
            APSSetVarAndUpdate status "Computing slopes for ${actuatorName}..."
            exec sddsslopes $outputFile ${dataDir}/${actuatorName}_Slopes.sdds \
              "-independentVariable=${actuatorName}" \
              "-col=Real,Imag" \
              "-exclude=PTB:CM:measCurrentCM,BTS:CM:q,${bpm}:sum"
            lappend actuatorSlopeList ${dataDir}/${actuatorName}_Slopes.sdds
        }
        APSSetVarAndUpdate status "Finished computing slopes."
        eval exec sddscombine -pipe=out $actuatorSlopeList \
          -merge -overWrite \
          | sddsconvert -pipe \
          "-dele=col,*Intercept" \
          | sddstranspose -pipe \
          | sddspseudoinverse -pipe=in ${dataDir}/longResponse.inv \
          -oldColumnNames=Actuators
        APSSetVarAndUpdate status "Finished computing pseudoinverse."
	set minSingular [exec sdds2stream -par=MinimumSingularValueRatio ${dataDir}/longResponse.inv]
	if {$minSingular!=0.0} {
	    APSSetVarAndUpdate status "Error: the minimum singular value ratio is not 0!"
	}
    }

    if $doPlot {
        APSSetVarAndUpdate status "Plotting longitudinal response data..."
        exec sddsplot -title= "-topline=Synchrotron Oscillation Real and Imaginary Parts vs Actuators" \
          "-col=StartRampTime,Real" -graph=symbol,vary=subtype,scale=2 ${dataDir}/StartRampTime.sdds \
          "-col=StartRampTime,Imag" -graph=line,vary -legend ${dataDir}/StartRampTime.sdds -end \
          "-col=RF12Phase,Real" -graph=symbol,vary=subtype,scale=2 ${dataDir}/RF12Phase.sdds \
          "-col=RF12Phase,Imag" -graph=line,vary ${dataDir}/RF12Phase.sdds -legend \&
        APSSetVarAndUpdate status "Done."
    }
}
