#!/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 CVSRevisionAuthor "\$Revision: 1.12 $ \$Author: sajaev $"
set CVSRevisionAuthor "\$Revision: 1.12 $ \$Author: sajaev $"

APSApplication . -name SRSextupoles -version 1 \
  -overview {This application is for various sextupole manipulations.}

#-----------------------------------------------------------------------------------------------------------------------

proc MakeMainFrame { args } {

    global applyButton restoreButton zeroButton estimatedChrom beamEnergy
    APSParseArguments {parent}

    #--- Beam energy part
    APSFrameGrid .grid -parent $parent -xList {x1 x2}
    set w $parent.grid.x1
    APSLabeledEntry .energy -parent $w -label "Beam energy:" -textVariable beamEnergy -width 10


    #--- Chromaticity estimate part 
    set estimatedChrom ""
    APSLabeledOutput .estimatedChrom -parent $parent \
      -label "Estimated chromaticity for current sextupoles:" -textVariable estimatedChrom -width 35
    APSButton .refresh -parent $parent.estimatedChrom \
      -text "Refresh" -size small \
      -command { 
          if [catch { EstimateCurrentChromaticity -beamEnergy $beamEnergy } estimatedChrom] {
              APSSetVarAndUpdate status "EstimateCurrentChromaticity: $estimatedChrom"
          } else {
              APSSetVarAndUpdate status "Estimated chromaticity refreshed."
          }
      } -contextHelp "Recalculates the estimated chromaticity for current sextupoles using lattice from \
                      oagData/calibratedModels/default"

    #--- Single step changes frame
    MakeSingleChangesFrame .singleChanges -parent $parent

    #--- Combined changes frame
    MakeCombinedChangesFrame .combinedChanges -parent $parent

    #--- Accumulated changes frame
    MakeAccumulatedChangesFrame .accumulatedChanges -parent $parent

    #--- Action buttons
    set applyButton $parent.changeSextupoles.button
    APSButton .changeSextupoles -parent $parent -text "Apply combined \nsextupole changes" -command \
      {
          APSDisableButton $applyButton
          APSDisableButton $restoreButton
          APSDisableButton $zeroButton
          if [catch {ApplyDeltaCurrents} result] {
              APSSetVarAndUpdate status "ApplyDeltaCurrents: $result"
          } else {
              if [catch {ZeroIntendedChanges} result] {
                  APSSetVarAndUpdate "ZeroIntendedChanges: $result"
              }
              set I(S1) [caget S1A:S1:CurrentAO]
              set I(S2) [caget S1A:S2:CurrentAO]
              set I(S3) [caget S1A:S3:CurrentAO]
              set I(S4) [caget S1A:S4:CurrentAO]
	      if [catch {exec $OAGGlobal(OAGLoggingDirectory)/SRLatticeParameters/computeLatticeParameters} result] {
		  APSSetVarAndUpdate status "Error setting chromaticity readback PV: $result"
		  APSSetVarAndUpdate status "Warning: Sextupoles were changed, but calculated chromaticity was not."
	      }
          }
          update idletasks
          APSEnableButton $applyButton
          APSEnableButton $restoreButton
          APSEnableButton $zeroButton
      } -contextHelp "Applies combined intended sextupole changes to the machine."
    
    set restoreButton $parent.restoreSextupoles.button
    APSButton .restoreSextupoles -parent $parent -text "Restore all sextupoles\nback" -command \
      {
          APSDisableButton $applyButton
          APSDisableButton $restoreButton
          APSDisableButton $zeroButton
          APSSetVarAndUpdate status "Ramping back..."
          if [catch {exec cavput -list=$restoreSextupolesString -pend=10 -ramp=step=10,pause=0.1} result] {
              APSSetVarAndUpdate status "cavput: $result"
          } else {
              APSSetVarAndUpdate status "Sextupoles have been restored."
          }
          
          update idletasks
          APSEnableButton $applyButton
          APSEnableButton $restoreButton
          APSEnableButton $zeroButton
      } -contextHelp "Return all sextupoles to the very beginning."
    
    set zeroButton $parent.zeroAll.button
    APSButton .zeroAll -parent $parent -text "Zero all \nintended changes" -command \
      {
          APSDisableButton $applyButton
          APSDisableButton $restoreButton
          APSDisableButton $zeroButton
          
          if [catch {ZeroIntendedChanges} result] {
              APSSetVarAndUpdate status "ZeroIntendedChanges: $result"
          } else {
              APSSetVarAndUpdate status "Intended changes zeroed."
          }
          
          update idletasks
          APSEnableButton $applyButton
          APSEnableButton $restoreButton
          APSEnableButton $zeroButton
      } -contextHelp "Zero all intended changes in order to start over."

}

#-----------------------------------------------------------------------------------------------------------------------

proc MakeSingleChangesFrame {widget args} {

    APSParseArguments {parent}

    global estButton runButton scrFile calcOfflineButton beamline lteFile beamEnergy

    APSFrame $widget -parent $parent -label "Single Step Changes"
    set w1 $parent$widget.frame
    set commandWidgetList [APSTabFrame .tabsMain -parent $w1 -width 800 -height 220 \
			       -labelList "\"Change chromaticity\" \"Change sextupoles\" \"Coefficients\" \
			       \"Off-line estimates\""  -label ""]
    set inputBoxLength 65
    MakeChromaticityTab .chromaticity -parent [lindex $commandWidgetList 0]
    MakeChangeSextupTab .changesextup -parent [lindex $commandWidgetList 1]
    MakeCoefficientsTab .coefficients -parent [lindex $commandWidgetList 2] -inputBoxLength $inputBoxLength
    MakeOfflineEstimTab .offlineestim -parent [lindex $commandWidgetList 3] -inputBoxLength $inputBoxLength

}

#-----------------------------------------------------------------------------------------------------------------------

proc MakeChromaticityTab { widget args } {

    global estButton1 percentAction family

    APSParseArguments { parent }

    APSFrameGrid .grid -parent $parent -xList {x1 x2}
    set w $parent.grid.x1
    APSRadioButtonFrame .sexFamiliesChrom -parent $w -label "Sextupole families to use" \
      -variable family -valueList {S12 S13 S24 S34} -buttonList {S1-S2 S1-S3 S2-S4 S3-S4} -orientation horizontal \
      -contextHelp "Chooses families to change chromaticity."
    
    APSLabeledEntry .xChromaticity -parent $w -label "X chromaticity change:" -textVariable Chromaticity(x) -width 30
    APSLabeledEntry .yChromaticity -parent $w -label "Y chromaticity change:" -textVariable Chromaticity(y) -width 30
    APSLabeledEntry .excludeSectors -parent $w -label "Exclude sectors: " -textVariable ExcludeSectors -width 50

    set estButton1 $parent.estimate.button
    APSButton .estimate -parent $parent -text "Estimate chromaticity changes" -command \
      {
	  if $percentAction {
	      APSSetVarAndUpdate status "You started percentage adjustment. Other actions are not allowed until the percentage \
                                             adjustment completed."
	      return
	  }
          APSDisableButton $estButton1
          if [catch {EstimateChanges_ChromTab} result] {
              APSSetVarAndUpdate status "EstimateChanges_ChromTab: $result"
          } else {
              APSSetVarAndUpdate status "[clock format [clock seconds] -format %T]"
              APSSetVarAndUpdate status "Estimate chromaticity changes - done."
          }
          update idletasks
          APSEnableButton $estButton1
      } -contextHelp "Estimates single step changes in chromaticity without applying them to the machine."
}

#-----------------------------------------------------------------------------------------------------------------------

proc MakeChangeSextupTab { widget args } {

    global estButton1 estButton2 on percentAction percentK2

    APSParseArguments { parent }

    APSFrameGrid .grid -parent $parent -xList {x1 x2}
    
    set w $parent.grid.x1
    APSLabeledEntry .deltaS1 -parent $w -label "S1 change (A):" -textVariable deltaI(S1) -width 10
    APSLabeledEntry .deltaS2 -parent $w -label "S2 change (A):" -textVariable deltaI(S2) -width 10
    APSLabeledEntry .deltaS3 -parent $w -label "S3 change (A):" -textVariable deltaI(S3) -width 10
    APSLabeledEntry .deltaS4 -parent $w -label "S4 change (A):              " -textVariable deltaI(S4) -width 10
    APSLabeledEntry .percent -parent $w -label "All together by % of K2 (%):" -textVariable percentK2 -width 10 \
	-contextHelp "Enter numbers like \"-5\". Unlike all other actions by this GUI that are done by averaging families, this will do true magnet by magnet adjustment. still the estimated numbers below are calculated on a by-family basis. Not combinable with any other actions. "
    set w $parent.grid.x2
    
    set estButton2 $parent.estimate.button
    APSButton .estimate -parent $parent -text "Estimate chromaticity changes" -command \
      {
	  if {$percentK2 != 0} {
	      #--- Percentage action should be done magnet by magnet. Unlike the other actions by this GUI, which are done
	      #--- on a by-family basis. Therefore the actions are not combinable.
	      #--- That's why we first zero all intended changes before doing percentage action, 
	      #--- thendisable both "Estimate changes" buttons after this action.
	      set percentK2copy $percentK2
              if [catch {ZeroIntendedChanges} result] {
                  APSSetVarAndUpdate "ZeroIntendedChanges: $result"
              }
	      set percentK2 $percentK2copy
	      APSDisableButton $estButton2 
	      APSDisableButton $estButton1
	      if [catch {EstimateChanges_Percent} result] {
		  APSSetVarAndUpdate status "EstimateChanges_Percent: $result"
	      } else {
		  set percentAction 1
		  APSSetVarAndUpdate status "[clock format [clock seconds] -format %T]"
		  APSSetVarAndUpdate status "Estimate chromaticity changes - done."
	      }
	  } else {
	      if $percentAction {
		  APSSetVarAndUpdate status "You started percentage adjustment. Other actions are not allowed until the percentage \
                                             adjustment completed."
		  return
	      }
	      APSDisableButton $estButton2
	      if [catch {EstimateChanges_SexTab} result] {
		  APSSetVarAndUpdate status "EstimateChanges_SexTab: $result"
	      } else {
		  APSSetVarAndUpdate status "[clock format [clock seconds] -format %T]"
		  APSSetVarAndUpdate status "Estimate chromaticity changes - done."
	      }
	      APSEnableButton $estButton2
	  }
          update idletasks
      } -contextHelp "Estimates single step changes in chromaticity without applying them to the machine."
    
}

#-----------------------------------------------------------------------------------------------------------------------

proc MakeCoefficientsTab { widget args } {

    global runButton OAGGlobal

    APSParseArguments { parent inputBoxLength }

    set lteFileDir $OAGGlobal(SRLatticesDirectory)

    APSLabeledEntry .lteEntry -parent $parent -label "Elegant .lte file:" \
	-textVariable lteFile -width $inputBoxLength -contextHelp \
	"Elegant .lte file with the lattice for which you want to calculate chromaticity coefficients."
    APSButton .dir -parent $parent.lteEntry \
	-text F -packOption "-side right" \
	-command "findFiles -dir $lteFileDir -pattern *.lte -fileVar lteFile" \
	-contextHelp "Bring up a file selection dialog box to choose the .lte elegant file."

    APSLabeledEntry .beamlineEntry -parent $parent -label "Beamline name:" \
	-textVariable beamline -width $inputBoxLength -contextHelp \
	"Beamline name to use in the elegant .lte file above."

    APSLabeledEntry .paramEntry -parent $parent -label "Parameter file (optional):" \
	-textVariable paramFile -width $inputBoxLength -contextHelp \
	"Elegant parameter file that corresponds to the lattice that corresponds to the scr file above."
    APSLabeledEntry .paramEntry1 -parent $parent -label "Parameter file (optional):" \
	-textVariable paramFile1 -width $inputBoxLength -contextHelp \
	"Elegant parameter file that corresponds to the lattice that corresponds to the scr file above."
#    APSButton .dir -parent $parent.paramEntry \
	-text F -packOption "-side right" \
	-command "findFiles -dir . -pattern * -fileVar paramFile" \
	-contextHelp "Bring up a file selection dialog box to choose the elegant parameter file."

    set runButton $parent.coefficients.button
    APSButton .coefficients -parent $parent -text "Recalculate coefficients" -command \
      {
          APSDisableButton $runButton
          if [catch {CalculateCoefficients -lteFile $lteFile -paramFile $paramFile -paramFile1 $paramFile1 \
			 -beamlineName $beamline} result] {
              APSSetVarAndUpdate status "$result"
          }
          update idletasks
          APSEnableButton $runButton
      } -contextHelp "Recalculates chromaticity coefficients using the specified above files."
}

#-----------------------------------------------------------------------------------------------------------------------

proc MakeOfflineEstimTab { widget args } {

    global calcOfflineButton excitationFile OAGGlobal

    APSParseArguments { parent inputBoxLength }

    set excitFileDir /home/helios/oagData/sr/magnets/sext
    set lteFileDir $OAGGlobal(SRLatticesDirectory)
    set scrFileDir /home/helios/oagData/SCR/snapshots/SR

    APSLabeledEntry .xrefEntry -parent $parent -label "Magnet Xref file:" \
	-textVariable xrefFile -width $inputBoxLength -contextHelp \
	"Sextupole cross-reference file corresponding to the date of interest. First change to the old file was done on \
         May 23 2006 due to S2 pole tips installed."
    APSButton .dir -parent $parent.xrefEntry \
	-text F -packOption "-side right" \
	-command "findFiles -dir $excitFileDir -pattern SSP_xref*sdds -fileVar xrefFile" \
	-contextHelp "Bring up a file selection dialog box to choose Sextupole cross-reference file."

    APSLabeledEntry .scrEntry -parent $parent -label "SR file:" \
	-textVariable scrFile -width $inputBoxLength -contextHelp \
	"SCR file to be used to take sextupole strengths for chromaticity calculations."
    APSButton .dir -parent $parent.scrEntry \
	-text F -packOption "-side right" \
	-command "findFiles -dir $scrFileDir -pattern SR*.gz -fileVar scrFile" \
	-contextHelp "Bring up a file selection dialog box to choose the SCR file."

    APSLabeledEntry .lteEntry -parent $parent -label "Elegant .lte file:" \
	-textVariable lteFile -width $inputBoxLength -contextHelp \
	"Elegant .lte file that corresponds to the lattice that corresponds to the scr file above."
    APSButton .dir -parent $parent.lteEntry \
	-text F -packOption "-side right" \
	-command "findFiles -dir $lteFileDir -pattern *.lte -fileVar lteFile" \
	-contextHelp "Bring up a file selection dialog box to choose the .lte elegant file."

    APSLabeledEntry .beamlineEntry -parent $parent -label "Beamline name:" \
	-textVariable beamline -width $inputBoxLength -contextHelp \
	"Beamline name to use in the elegant .lte file above."

    APSLabeledEntry .paramEntry -parent $parent -label "Parameter file\n(optional):" \
	-textVariable paramFile -width $inputBoxLength -contextHelp \
	"Elegant parameter file that corresponds to the lattice that corresponds to the scr file above."
    APSButton .dir -parent $parent.paramEntry \
	-text F -packOption "-side right" \
	-command "findFiles -dir . -pattern * -fileVar paramFile" \
	-contextHelp "Bring up a file selection dialog box to choose the elegant parameter file."

    set calcOfflineButton $parent.calcOffline.button
    APSButton .calcOffline -parent $parent -text "Calculate chromaticity" -command \
      {
          APSDisableButton $calcOfflineButton
          if [catch {CalculateOfflineChromaticity -scrFile $scrFile -lteFile $lteFile -xrefFile $xrefFile \
			 -paramFileList $paramFile -beamEnergy $beamEnergy -beamline $beamline} calcOfflineChrom] {
              APSSetVarAndUpdate status "CalculateOfflineChromaticity: $calcOfflineChrom"
          } else {
              APSSetVarAndUpdate status "Estimate chromaticity - done."
          }
          update idletasks
          APSEnableButton $calcOfflineButton
      } -contextHelp "Estimates chromaticity using sextupole settings from specified scr file and lattice from \
                      specified elegant file."


}

#-----------------------------------------------------------------------------------------------------------------------

proc findFiles {args} {
    set fileVar ""
    APSParseArguments {dir pattern fileVar}
    global $fileVar
    set file [set $fileVar] 
    if [string length $file] {
        set dir [file dir $file]
    }
    set choosedfile [APSFileSelectDialog .chooseInputFile -listDir $dir -pattern $pattern]
    if [string length $choosedfile] {
        set $fileVar $choosedfile
    }
} 

#-----------------------------------------------------------------------------------------------------------------------

proc MakeCombinedChangesFrame {widget args} {

    APSParseArguments {parent}

    APSFrame $widget -parent $parent -label "Combined Intended Changes"
    set w1 $parent$widget.frame
    
    APSFrameGrid .grid1 -parent $w1 -xList {x1 x2 x3}
    
    set w $w1.grid1.x1
    APSLabeledOutput .deltaS1total -parent $w -label "S1 change (A):" -textVariable deltaItotal(S1) -width 12
    APSLabeledOutput .deltaS2total -parent $w -label "S2 change (A):" -textVariable deltaItotal(S2) -width 12
    APSLabeledOutput .deltaS3total -parent $w -label "S3 change (A):" -textVariable deltaItotal(S3) -width 12
    APSLabeledOutput .deltaS4total -parent $w -label "S4 change (A):" -textVariable deltaItotal(S4) -width 12
    
    set w $w1.grid1.x2
    APSLabeledOutput .s1I -parent $w -label "S1 (A):" -textVariable I(S1) -width 10
    APSLabeledOutput .s2I -parent $w -label "S2 (A):" -textVariable I(S2) -width 10
    APSLabeledOutput .s3I -parent $w -label "S3 (A):" -textVariable I(S3) -width 10
    APSLabeledOutput .s4I -parent $w -label "S4 (A):" -textVariable I(S4) -width 10
    
    set w $w1.grid1.x3
    APSLabeledOutput .xChromaticity -parent $w -label "X chromaticity change:" -textVariable ChromaticityTotal(x) -width 10
    APSLabeledOutput .yChromaticity -parent $w -label "Y chromaticity change:" -textVariable ChromaticityTotal(y) -width 10

}

#-----------------------------------------------------------------------------------------------------------------------

proc MakeAccumulatedChangesFrame {widget args} {

    APSParseArguments {parent}

    APSFrame $widget -parent $parent -label "Accumulated Applied Changes"
    set w1 $parent$widget.frame
    
    APSFrameGrid .grid1 -parent $w1 -xList {x1 x2}
    
    set w $w1.grid1.x1
    APSLabeledOutput .xChromaticity -parent $w -label "X chromaticity change:     " \
	-textVariable ChromaticityAccum(x) -width 10

    set w $w1.grid1.x2
    APSLabeledOutput .yChromaticity -parent $w -label "   Y chromaticity change:     " \
	-textVariable ChromaticityAccum(y) -width 10
     
}

#-----------------------------------------------------------------------------------------------------------------------
#--- This procedure transforms currents to K2s or K2s to currents

proc sexSetpoints { args } {

    global excitationFile beamEnergy
    set sexName ""
    set I ""
    set K2 ""

    APSParseArguments {sexName I K2}
    if {![string length $sexName] || ![expr [string length $I] + [string length $K2]]} {
        puts stderr $argv
        puts stderr $usage
        exit
    }

    set sexLength 0.2527
    set Hr [expr $beamEnergy / 0.299792]

    switch -exact -- $sexName {
	S1 { set sign 1 }
	S2 { set sign -1 }
	S3 { set sign -1 }
	S4 { set sign 1 }
	default { return -code error "Wrong sextupole name!" }
    }
    set BnLcolumn $sexName-BnL

    if {[string length $I] != 0 } {
	#--- Transforming currents to K2s...
        set B2L [exec sddsinterp $excitationFile -pipe=out -col=I,$BnLcolumn -atValues=$I \
                   -aboveRange=extrapolate -belowRange=extrapolate \
                   | sdds2stream -pipe=in -col=$BnLcolumn]
        set K2 [expr $B2L / $Hr / $sexLength * $sign]
        set output $K2
    } else {
        set B2L [expr $K2 * $Hr * $sexLength * $sign]
        set I [exec sddsinterp $excitationFile -pipe=out -col=$BnLcolumn,I -atValues=$B2L \
                 -aboveRange=extrapolate -belowRange=extrapolate \
                 | sdds2stream -pipe=in -col=I]
        set output $I
    }
    return $output
}

#-----------------------------------------------------------------------------------------------------------------------

proc EstimateChanges_ChromTab { args } {

    global Ainv I Chromaticity deltaItotal ChromaticityTotal deltaI family

    APSSetVarAndUpdate status "estimate chromaticity changes with family $family."
    foreach sext {S1 S2 S3 S4} {
        set deltaI($sext) 0
        set Iold($sext) [expr $I($sext) + $deltaItotal($sext)]
    }

    switch $family {
        S12 {
            set sexList {S1 S2}
        }
        S13 {
            set sexList {S1 S3}
        }
        S24 {
            set sexList {S2 S4}
        }
        S34 {
            set sexList {S3 S4}
        }
        default {
            return -code error "Invalid code for sextupole families: $family"
        }
    }
    foreach sext $sexList {
        set deltaK2($sext) [exec rpnl "$Ainv(${sext}-1) $Chromaticity(x) * $Ainv(${sext}-2) $Chromaticity(y) * + "]
        set K2old($sext)   [sexSetpoints -sexName $sext -I $Iold($sext)]
        set K2new($sext)   [expr $K2old($sext) + $deltaK2($sext)]
        set Inew($sext)    [sexSetpoints -sexName $sext -K2 $K2new($sext)]
        set deltaI($sext)  [expr $Inew($sext) - $Iold($sext)]
    }

    foreach sext {S1 S2 S3 S4} {
        set deltaItotal($sext) [format "%12.6f" [expr $deltaItotal($sext) + $deltaI($sext)]]
        set deltaI($sext) 0
    }
    array set Chromaticity "x 0 y 0"
    APSSetVarAndUpdate status "calculate total chromaticity..."
    CalculateTotalChromaticity
    APSSetVarAndUpdate status "done."
}

#-----------------------------------------------------------------------------------------------------------------------

proc CalculateTotalChromaticity { } {
    global I A deltaItotal ChromaticityTotal chromX chromY
    foreach sext {S1 S2 S3 S4} {
        set Inew($sext)    [expr $I($sext) + $deltaItotal($sext)]
        set K2old($sext)   [sexSetpoints -sexName $sext -I $I($sext)]
        set K2new($sext)   [sexSetpoints -sexName $sext -I $Inew($sext)]
        set deltaK2($sext) [expr $K2new($sext) - $K2old($sext)]
    }
    set ChromaticityTotal(x) \
      [format "%12.6f" \
         [exec rpnl "$A(11) $deltaK2(S1) * $A(12) $deltaK2(S2) * + $A(13) $deltaK2(S3) * + $A(14) $deltaK2(S4) * +"]]
    set ChromaticityTotal(y) \
      [format "%12.6f" \
         [exec rpnl "$A(21) $deltaK2(S1) * $A(22) $deltaK2(S2) * + $A(23) $deltaK2(S3) * + $A(24) $deltaK2(S4) * +"]]
    set chromX [expr $chromX + $ChromaticityTotal(x)]
    set chromY [expr $chromY + $ChromaticityTotal(y)]
    update
    pv putw {chromX chromY}
}

#-----------------------------------------------------------------------------------------------------------------------

proc EstimateChanges_SexTab { } {

    global I A deltaItotal ChromaticityTotal deltaI

    foreach sext {S1 S2 S3 S4} {
        set deltaItotal($sext) [format "%12.6f" [expr $deltaItotal($sext) + $deltaI($sext)]]
        set deltaI($sext) 0
    }
    CalculateTotalChromaticity

}

#-----------------------------------------------------------------------------------------------------------------------

proc EstimateChanges_Percent { } {

    global tmpDir xrefFile beamEnergy BRhoPVName I deltaItotal ChromaticityTotal deltaI percentK2 percentFile
    global controlNameList controlNameVarList sextupoleCurrent

    #--- Making scr-like file with sextupoles...
    set tmpRoot $tmpDir/[APSTmpString]-percentK2
    pv getw $controlNameVarList
    foreach pv $controlNameList {
        lappend valueStringList $sextopleCurrent($pv)
    }
    if [catch {exec sddsmakedataset -pipe=out -col=ControlName,type=string -data=[join $controlNameList ,] \
                 -col=ValueString,type=string -data=[join $valueStringList ,]  \
                 | sddsprocess -pipe=in $tmpRoot.sext -print=para,SnapshotDescription,Dummy} result] {
	return -code error "Error doing cavget: $result"
    }
    lappend deleteFiles $tmpRoot.sext

    #--- Make present K2 file:
    set outputFileDir [file dirname $tmpRoot]
    set outputFileRoot [file tail $tmpRoot]
    if [catch {APSMpMagnetKnLValues -SCRFile $tmpRoot.sext -xrefFileList $xrefFile \
		   -energy $beamEnergy -BRhoPVName $BRhoPVName \
		   -outputFileDir $outputFileDir \
		   -outputFileRoot $outputFileRoot \
		   -statusCallback "APSSetVarAndUpdate status" \
		   -abortVariable abortRun} result] {
	return -code error "APSMpMagnetKnLValues: $result"
    }
    lappend deleteFiles $tmpRoot.KnL

    #--- Make new K2 file suitable for setpoints:
    exec sddsprocess $tmpRoot.KnL $tmpRoot.Knnew "-redef=col,ParameterValue,ParameterValue 1 $percentK2 100 / + *" -print=col,ElementType,SEXT
    exec sddsprocess $tmpRoot.KnL $tmpRoot.length -redef=col,ParameterValue,Length -reprint=col,ElementParameter,L
    exec sddscombine $tmpRoot.Knnew $tmpRoot.length $tmpRoot.KnLnew -merge -overwrite
    lappend deleteFiles $tmpRoot.KnLnew  $tmpRoot.length $tmpRoot.Knnew 

    #--- Make new current file:
    set directory /home/helios/SR/controlFiles
    set templateDir /home/helios/oagData/sr/magnetConditioning/templates
    set xrefFile $directory/SS_xref.sdds
    set templateFile $templateDir/SS_stand.sdds
    if [catch {APSMpMagnetSetpoints -paramFile $tmpRoot.KnLnew \
		   -xrefFileList $xrefFile \
		   -templateFileList $templateFile \
		   -energy $beamEnergy -BRhoPVName $BRhoPVName \
		   -outputFileDir $outputFileDir -outputFileRoot $outputFileRoot \
		   -statusCallback "APSSetVarAndUpdate status" \
		   -abortVariable abortRun} result] {
	return -code error "APSMpMagnetSetpoints: $result"
    }
    set percentFile $tmpRoot.snp

    #--- Calculate average deltaI by families since it is how the program works:
    if [catch {exec sddsxref $tmpRoot.snp $tmpRoot.sext -pipe=out -take=ValueString -rename=col,ValueString=ValueString0 -match=ControlName \
		   | sddsprocess -pipe -scan=col,Value,ValueString,%lf -scan=col,Value0,ValueString0,%lf \
		   "-redef=col,deltaI,Value Value0 -" "-edit=col,SextFamily,ControlName,%@:CurrentAO@@ Z:" \
		   | sddssort -pipe -col=SextFamily \
		   | sddsbreak -pipe -change=SextFamily \
		   | sddsprocess -pipe -process=deltaI,aver,DeltaIaver -process=SextFamily,first,SextFamily \
		   | sdds2stream -pipe=in -para=SextFamily,DeltaIaver} deltaIList] {
	return -code error "Error calculating average delta I: $deltaIList"
    }
    array set deltaI $deltaIList
    
    #--- Update all numbers in the GUI:
    foreach sext {S1 S2 S3 S4} {
        set deltaItotal($sext) [format "%12.6f" [expr $deltaItotal($sext) + $deltaI($sext)]]
        set deltaI($sext) 0
    }
    set percentK2 0
    CalculateTotalChromaticity
    eval file delete $deleteFiles
}

#-----------------------------------------------------------------------------------------------------------------------

proc EstimateCurrentChromaticity { args } {

    global tmpDir xrefFile

    APSParseArguments { beamEnergy }

    global controlNameList controlNameVarList sextopleCurrent
    pv getw $controlNameVarList
    
    set tmpRoot /tmp/[APSTmpString]
    foreach pv $controlNameList {
	lappend valueStringList $sextopleCurrent($pv)
    }
    exec sddsmakedataset -pipe=out -col=ControlName,type=string -data=[join $controlNameList ,] \
	-col=ValueString,type=string -data=[join $valueStringList ,] \
	-col=ParameterValue,type=double -data=[join $valueStringList ,] \
	| sddsprocess -pipe=in $tmpRoot.sext -print=para,SnapshotDescription,Dummy
    lappend tmpFileList $tmpRoot.sext


    #--- Running CalculateOfflineChromaticity with scr file created above...
    # Using the calibrated model is good.
    set measDirectory /home/helios/oagData/sr/calibratedModels/default
    set lteFile $measDirectory/aps.lte
    set beamline RING
    if [catch {exec sdds2stream $measDirectory/requiredParamFiles.sdds -col=filename} fileList] {
	return -code error "Error reading requiredParamFiles.sdds file: $fileList"
    }
    set paramFileList ""
    # Using the parameter files of the calibrated model is good.
    foreach filename $fileList { lappend parameterFileList $measDirectory/$filename }
    if [catch {CalculateOfflineChromaticity -scrFile $tmpRoot.sext -lteFile $lteFile -xrefFile $xrefFile \
		   -paramFileList $paramFileList -beamEnergy $beamEnergy -beamline $beamline} outputString] {
	return -code error "CalculateOfflineChromaticity: $outputString"
    }

    eval file delete $tmpFileList
    return $outputString
}

#-----------------------------------------------------------------------------------------------------------------------

proc CalculateOfflineChromaticity { args } {

    global tmpDir BRhoPVName chromX chromY

    APSParseArguments { scrFile lteFile paramFileList beamEnergy beamline xrefFile }

    set tmpRoot $tmpDir/[APSTmpString]-offlineChrom

    #--- Making KnL file from scr file...
    set outputFileDir [file dirname $tmpRoot]
    set outputFileRoot [file tail $tmpRoot]
    if [catch {APSMpMagnetKnLValues -SCRFile $scrFile -xrefFileList $xrefFile \
		   -energy $beamEnergy -BRhoPVName $BRhoPVName \
		   -outputFileDir $outputFileDir \
		   -outputFileRoot $outputFileRoot \
		   -statusCallback "APSSetVarAndUpdate status" \
		   -abortVariable abortRun} result] {
	return -code error "APSMpMagnetKnLValues: $result"
    }
    lappend tmpFileList $tmpRoot.KnL

    #--- Making elegant file for chromaticity run...
    set eleFile $tmpRoot.ele
    set twiFile $tmpRoot.twi
    set sexFile $tmpRoot.KnL
    # usually called with calibrated model for the lte and parameter files.
    if [catch {GenerateElegantFileFromLTE -eleOutputFile $eleFile \
		   -run_setup [list "lattice $lteFile use_beamline $beamline default_order 2"] \
		   -load_parameters [list "filename_list \"$paramFileList\"" \
					 "filename $sexFile change_defined_values 1"] \
		   -twiss_output [list "filename $twiFile"] \
		   -run_control [list "n_steps 1"] \
		   -bunched_beam [list "n_particles_per_bunch 1"] \
	       } result] {
	return -code error "Fit_GenerateElegantFileFromLTE: $result"
    }
    lappend tmpFileList $eleFile $twiFile $sexFile

    #--- Running elegant...
    set eleOutFile $tmpRoot.out
    file delete $eleOutFile
    APSSetVarAndUpdate status "CalculateOfflineChromaticity: Running elegant..."
    if [catch {exec elegant $eleFile > $eleOutFile} result] {
        return -code error "elegant error (see file $eleOutFile): $result"
    }
    lappend tmpFileList $eleOutFile
    set chromX [exec sdds2stream $twiFile -para=dnux/dp]
    set chromY [exec sdds2stream $twiFile -para=dnuy/dp]
    APSSetVarAndUpdate status "cavput -list=SR:CompLatParam:ChromX=$chromX"
    APSSetVarAndUpdate status "cavput -list=SR:CompLatParam:ChromX=$chromY"
    catch {exec cavput -list=SR:CompLatParam:ChromX=$chromX -pend=1}
    catch {exec cavput -list=SR:CompLatParam:ChromY=$chromY -pend=1}
    set outputString "CHROMX [format "%8.2f" $chromX],  CHROMY [format "%8.2f" $chromY]"
    APSSetVarAndUpdate status "CHROMX = [format "%8.2f" $chromX],  CHROMY = [format "%8.2f" $chromY]"
    #if [catch {exec cavput -list=SR:CompLatParam:ChromX=$chromX,SR:CompLatParam:ChromY=$chromY -pend=10} result] {
    #    APSSetVarAndUpdate status  "Error setting chromaticity pvs: $result"
    #}
    pv putw chromX
    pv putw chromY
    eval file delete $tmpFileList
    return $outputString
}

#-----------------------------------------------------------------------------------------------------------------------

proc ApplyDeltaCurrents { } {

    global deltaItotal ChromaticityTotal ExcludeSectors ChromaticityAccum percentAction percentFile
    if $percentAction {
	APSSetVarAndUpdate status "Restoring file: $percentFile"
	global estButton1 estButton2
	APSEnableButton $estButton2 
	APSEnableButton $estButton1
	if [catch {exec sddscasr $percentFile -restore} result] {
	    return -code error "Error doing sddscasr: $result"
	}
    } else {
	set    cavputString "A:S1:CurrentAO=$deltaItotal(S1),"
	append cavputString "B:S1:CurrentAO=$deltaItotal(S1),"
	append cavputString "A:S2:CurrentAO=$deltaItotal(S2),"
	append cavputString "B:S2:CurrentAO=$deltaItotal(S2),"
	append cavputString "A:S3:CurrentAO=$deltaItotal(S3),"
	append cavputString "B:S3:CurrentAO=$deltaItotal(S3),"
	append cavputString "A:S4:CurrentAO=$deltaItotal(S4)"
	set ExcludeSectors [string trim $ExcludeSectors]
	set excludeList 0
	if [string length $ExcludeSectors] {
	    foreach item [split $ExcludeSectors " ,"] {
		lappend excludeList $item
	    }
	}
	set sectorList ""
	for {set sector 1} {$sector<41} {incr sector} {
	    if [lsearch -exact $excludeList $sector]==-1 {
		lappend sectorList $sector
	    }
	}
	APSSetVarAndUpdate status "ramping..."
	if [catch {exec cavput -list=S -list=[join $sectorList ,] -list=$cavputString \
		       -delta -pend=10 -ramp=step=10,pause=0.1} result] {
	    return -code error "cavput: $result"
	}
    }
    APSSetVarAndUpdate status "[clock format [clock seconds] -format %T]"
    APSSetVarAndUpdate status \
	"The following changes have been applied:\
             \nS1=$deltaItotal(S1)  S2=$deltaItotal(S2)  S3=$deltaItotal(S3)  S4=$deltaItotal(S4) \
             \nCHROMX= $ChromaticityTotal(x)  CHROMY= $ChromaticityTotal(y)"
    set ChromaticityAccum(x) [format %6.3f [expr $ChromaticityAccum(x) + $ChromaticityTotal(x)]]
    set ChromaticityAccum(y) [format %6.3f [expr $ChromaticityAccum(y) + $ChromaticityTotal(y)]]
}

#-----------------------------------------------------------------------------------------------------------------------

proc CalculateCoefficients { args } {

    APSStrictParseArguments { lteFile paramFile paramFile1 beamlineName }

    global tmpDir A Ainv beamEnergy

    set scanParamFile $tmpDir/[APSTmpString]-chromCoeff.param
    set eleFile $tmpDir/[APSTmpString]-chromCoeff.ele
    set twiFile $tmpDir/[APSTmpString]-chromCoeff.twi
    if [catch {CreateParamFile -paramFile $scanParamFile} result] {
        return -code error "CalculateCoefficients: $result"
    }
    set paramFileList ""
    if [string length $paramFile] {set paramFileList $paramFile}
    if [string length $paramFile1] {set paramFileList [concat $paramFile $paramFile1]}
    if [catch {GenerateElegantFileFromLTE -eleOutputFile $eleFile \
			   -run_setup [list "lattice $lteFile use_beamline $beamlineName default_order 2"] \
			   -load_parameters [list "filename_list \"$paramFileList\"" \
						"filename $scanParamFile change_defined_values 0"] \
			   -twiss_output [list "filename $twiFile"] \
			   -run_control [list "n_steps 5"] \
			   -bunched_beam [list "n_particles_per_bunch 1"] \
		       } result] {
                return -code error "Fit_GenerateElegantFileFromLTE: $result"
	    }

    lappend tmpFileList $scanParamFile $eleFile $twiFile

    APSSetVarAndUpdate status "CalculateCoefficients: Running elegant..."
    file delete elegant.out
    if [catch {exec elegant $eleFile > elegant.out} result] {
        return -code error "elegant: $result"
    }
    lappend tmpFileList elegant.out
    set xChromList [exec sdds2stream $twiFile -para=dnux/dp]
    set yChromList [exec sdds2stream $twiFile -para=dnuy/dp]

    set A(11) [expr [lindex $xChromList 1] - [lindex $xChromList 0]]
    set A(12) [expr [lindex $xChromList 2] - [lindex $xChromList 0]]
    set A(13) [expr [lindex $xChromList 3] - [lindex $xChromList 0]]
    set A(14) [expr [lindex $xChromList 4] - [lindex $xChromList 0]]
    set A(21) [expr [lindex $yChromList 1] - [lindex $yChromList 0]]
    set A(22) [expr [lindex $yChromList 2] - [lindex $yChromList 0]]
    set A(23) [expr [lindex $yChromList 3] - [lindex $yChromList 0]]
    set A(24) [expr [lindex $yChromList 4] - [lindex $yChromList 0]]

    set deter34 [exec rpnl "$A(13) $A(24) * $A(14) $A(23) * -"]
    set deter12 [exec rpnl "$A(11) $A(22) * $A(12) $A(21) * -"]
    set Ainv(S1-1) [expr $A(22) / $deter12]
    set Ainv(S1-2) [expr $A(12) / $deter12 * -1]
    set Ainv(S2-1) [expr $A(21) / $deter12 * -1]
    set Ainv(S2-2) [expr $A(11) / $deter12]
    set Ainv(S3-1) [expr $A(24) / $deter34]
    set Ainv(S3-2) [expr $A(14) / $deter34 * -1]
    set Ainv(S4-1) [expr $A(23) / $deter34 * -1]
    set Ainv(S4-2) [expr $A(13) / $deter34]

    APSSetVarAndUpdate status "Direct:"
    APSSetVarAndUpdate status \
      "[format "%8.4f" $A(11)] [format "%8.4f" $A(12)] [format "%8.4f" $A(13)] [format "%8.4f" $A(14)]" 
    APSSetVarAndUpdate status \
      "[format "%8.4f" $A(21)] [format "%8.4f" $A(22)] [format "%8.4f" $A(23)] [format "%8.4f" $A(24)]" 
    APSSetVarAndUpdate status "Inverse:"
    APSSetVarAndUpdate status \
      "[format "%8.4f" $Ainv(S1-1)] [format "%8.4f" $Ainv(S1-2)] [format "%8.4f" $Ainv(S2-1)] [format "%8.4f" $Ainv(S2-2)]" 
    APSSetVarAndUpdate status \
      "[format "%8.4f" $Ainv(S3-1)] [format "%8.4f" $Ainv(S3-2)] [format "%8.4f" $Ainv(S4-1)] [format "%8.4f" $Ainv(S4-2)]" 

    eval file delete $tmpFileList
    APSSetVarAndUpdate status "Coefficients are done."
}

#-----------------------------------------------------------------------------------------------------------------------

proc CreateParamFile {args} {

    APSParseArguments { paramFile }

    if [catch {open $paramFile w} fid] {
        return -code error "$fid"
    }
    puts $fid "SDDS1"
    puts $fid "&column name=ElementName, type=string,  &end"
    puts $fid "&column name=ElementParameter, type=string,  &end"
    puts $fid "&column name=ParameterValue, type=double,  &end"
    puts $fid "&column name=ParameterMode, type=string,  &end"
    puts $fid "&data mode=ascii, no_row_counts=1, &end"
    for {set sector 1} {$sector < 41} {incr sector} {
        puts $fid " S${sector}A:S1  K2  0.0  differential "
        puts $fid " S${sector}B:S1  K2  0.0  differential "
    }
    puts $fid "  "
    for {set sector 1} {$sector < 41} {incr sector} {
        puts $fid " S${sector}A:S1  K2  1.0  differential "
        puts $fid " S${sector}B:S1  K2  1.0  differential "
    }
    puts $fid "  "
    for {set sector 1} {$sector < 41} {incr sector} {
        puts $fid " S${sector}A:S2  K2  1.0  differential "
        puts $fid " S${sector}B:S2  K2  1.0  differential "
    }
    puts $fid "  "
    for {set sector 1} {$sector < 41} {incr sector} {
        puts $fid " S${sector}A:S3  K2  1.0  differential "
        puts $fid " S${sector}B:S3  K2  1.0  differential "
    }
    puts $fid "  "
    for {set sector 1} {$sector < 41} {incr sector} {
        puts $fid " S${sector}A:S4  K2  1.0  differential "
    }
    puts $fid "  "
    close $fid
}

#-----------------------------------------------------------------------------------------------------------------------

proc GenerateElegantFileFromLTE { args } {
    set argList [list run_setup load_parameters alter_elements load_parameters2 run_control correct closed_orbit \
		     correction_matrix_output twiss_output bunched_beam]
    foreach arg $argList {set $arg ""}
    set eleOutputFile ""
    APSParseArguments [concat $argList eleOutputFile]

    array set run_setup_Array [list lattice "" use_beamline "" p_central_mev 7e3 default_order 1 concat_order 1 rootname "" \
				   parameters "" centroid ""]
    array set load_parameters_Array [list filename "" filename_list "" allow_missing_elements 1 allow_missing_parameters 1 \
					 change_defined_values 1]
    array set alter_elements_Array [list name "" type "" item "" value "" allow_missing_elements 1]
    array set run_control_Array [list n_steps 1]
    array set correct_Array [list mode orbit method global verbose 0 n_iterations 0 n_xy_cycles 1 \
				 correction_fraction [list 1.0 1.0] corrector_tweek [list 1e-5 1e-5] fixed_length 0 \
				 fixed_length_matrix 0]
    array set closed_orbit_Array [list output "" output_monitors_only 1 fixed_length 0]
    array set correction_matrix_output_Array [list response "" output_at_each_step 1 fixed_length 0]
    array set twiss_output_Array [list filename "" radiation_integrals 0 output_at_each_step 1 matched 1 reference_file "" \
				      reference_element ""]
    array set bunched_beam_Array [list n_particles_per_bunch 1]

    if [catch {open $eleOutputFile w} fileId] {
        return -code error "Cannot open the file $eleOutputFile for writing: $fileId"
    }
    foreach command $argList {
	if [string length [set $command]] {
	    #------ command is a list of lists of options to allows for multiple same-name commands (like load_parameters)
	    set commandList [set $command]
	    if {[string compare $command load_parameters2] == 0} {set command load_parameters}
	    foreach singleCommand $commandList {
		array set optionsArray $singleCommand
		array set defaultOptionsArray [array get ${command}_Array]
		foreach option [array names optionsArray] {set defaultOptionsArray($option) $optionsArray($option)}
		#------ Cannot have load_parameters with empty filename and filename_list - elegant gives error.
		if {[string compare $command load_parameters] == 0} {
		    foreach option [array names optionsArray] {set defaultOptionsArray($option) $optionsArray($option)}
		    if {![string length $defaultOptionsArray(filename)] \
			    && ![string length $defaultOptionsArray(filename_list)]} {
			unset optionsArray
			unset defaultOptionsArray
			continue
		    }
		}
		puts $fileId "&$command"
		foreach option [array names defaultOptionsArray] {
		    if [string length $defaultOptionsArray($option)] {
			if {[llength $defaultOptionsArray($option)] == 1} {
			    puts $fileId "   $option = $defaultOptionsArray($option),"
			} else {
			    if {[string compare $option filename_list] == 0} {
				puts $fileId "   $option = \"$defaultOptionsArray($option),\""
			    } else {
				puts $fileId "   ${option}\[0\] = [join $defaultOptionsArray($option) ,],"
			    }
			}
		    }
		}
		puts $fileId "&end"
		puts $fileId " "
		unset optionsArray
		unset defaultOptionsArray
	    }
	}
    }

    puts $fileId "&track &end"
    puts $fileId " "
    puts $fileId "&stop &end"
    
    close $fileId
}

#-----------------------------------------------------------------------------------------------------------------------
set first 1
proc GetAverageSextupoleCurrents { args } {

    APSParseArguments {restoreString}
    global controlNameList controlNameVarList sextopleCurrent first
    
    set tol 1.0
    APSSetVarAndUpdate status "Getting sextupole settings..."
    if $restoreString {
        if [catch {exec cavget -list=S -range=beg=1,end=40 -list=A:S1,A:S2,A:S3,A:S4,B:S3,B:S2,B:S1 -list=:CurrentAO \
                     -cavputForm -pend=10} restoreSextupolesString] {
            return -code error "$restoreSextupolesString"
        }
    }
    if $first {
        set controlNameList ""
        set controlNameVarList ""
        if [catch {exec cavget -list=S -range=beg=1,end=40 -list=A:S1,A:S2,A:S3,A:S4,B:S3,B:S2,B:S1 \
                     -list=:CurrentAO -label} currentList] {
            return -code error "Error doing cavget: $currentList"
        }
        set N [llength $currentList]
        if {$N != 560} { return -code error "cavget: Less than 280 sextupoles returned." }
        for {set I 0} {$I <$N} {incr I 2} {
            set PV [lindex $currentList $I]
            lappend controlNameList [lindex $currentList $I]
            lappend controlNameVarList sextopleCurrent($PV)
            lappend valueStringList [lindex $currentList [expr $I + 1]]
        }
        pv linkw $controlNameVarList $controlNameList
        set first 0
    } else {
        pv getw $controlNameVarList
        foreach pv $controlNameList {
            lappend valueStringList $sextopleCurrent($PV)
        }
    }
    if [catch {exec sddsmakedataset -pipe=out -col=ControlName,type=string -data=[join $controlNameList ,] \
		   -col=Value,type=double -data=[join $valueStringList ,] \
		   | sddsprocess -pipe \
		   -process=Value,average,S1Av,match=ControlName,value=*:S1:* \
		   -process=Value,average,S2Av,match=ControlName,value=*:S2:* \
		   -process=Value,average,S3Av,match=ControlName,value=*:S3:* \
		   -process=Value,average,S4Av,match=ControlName,value=*:S4:* \
		   -process=Value,standarddeviation,S1Stdev,match=ControlName,value=*:S1:* \
		   -process=Value,standarddeviation,S2Stdev,match=ControlName,value=*:S2:* \
		   -process=Value,standarddeviation,S3Stdev,match=ControlName,value=*:S3:* \
		   -process=Value,standarddeviation,S4Stdev,match=ControlName,value=*:S4:* \
		   | sdds2stream -pipe=in -param=S1Av,S1Stdev,S2Av,S2Stdev,S3Av,S3Stdev,S4Av,S4Stdev} valueList] {
	return -code error "Error processing cavget: $valueList"
    }

    if {([lindex $valueList 1] > $tol) || ([lindex $valueList 3] > $tol) \
	    || ([lindex $valueList 5] > $tol) || ([lindex $valueList 7] > $tol)} {
        APSInfoWindow .bigSigma -width 20 -infoMessage "Warning...\nSextupoles vary too much within families.\
            The corrections may not be correct. The program calculates dK2 values, then uses averaged over families currents \
            to calculate dI."
    }
    if $restoreString {
        return [list $restoreSextupolesString [format %8.3f [lindex $valueList 0]] [format %8.3f [lindex $valueList 2]] \
		    [format %8.3f [lindex $valueList 4]] [format %8.3f [lindex $valueList 6]]]
    } else {
        return [list [format %8.3f [lindex $valueList 0]] [format %8.3f [lindex $valueList 2]] \
		    [format %8.3f [lindex $valueList 4]] [format %8.3f [lindex $valueList 6]]]
    }
	
}

#-----------------------------------------------------------------------------------------------------------------------

proc ZeroIntendedChanges { } {

    global Chromaticity ChromaticityTotal deltaI deltaItotal percentK2 percentAction
    foreach plane {x y} {
        set Chromaticity($plane) 0
        set ChromaticityTotal($plane) 0
    }
    foreach sext {S1 S2 S3 S4} {
        set deltaI($sext) 0
        set deltaItotal($sext) 0
    }
    set percentK2 0
    set percentAction 0
}

proc UpdateBeamEnergy {args} {
    global BRho beamEnergy c_mks

    set beamEnergy [expr $BRho * $c_mks]
}

#-----------------------------------------------------------------------------------------------------------------------

set beamEnergy 7.0
array set Chromaticity "x 0 y 0"
array set ChromaticityTotal "x 0 y 0"
array set ChromaticityAccum "x 0 y 0"
set ExcludeSectors ""
set family S34
array set deltaI "S1 0 S2 0 S3 0 S4 0"
array set deltaItotal "S1 0 S2 0 S3 0 S4 0"
set percentK2 0
set percentAction 0

#Coefficients for the ideal lower-emittance lattice
set A(11)  4.991
set A(12)  0.586
set A(13)  0.541
set A(14)  4.017
set A(21) -3.693
set A(22) -2.799
set A(23) -3.743
set A(24) -2.489

set Ainv(S1-1)  0.2371
set Ainv(S1-2)  0.0496
set Ainv(S2-1) -0.3128
set Ainv(S2-2) -0.4228
set Ainv(S3-1) -0.1818
set Ainv(S3-2) -0.2935
set Ainv(S4-1)  0.2734
set Ainv(S4-2)  0.0395

set status ""
APSScrolledStatus .status -parent .userFrame -textVariable status -width 80 -height 7

if [catch {GetAverageSextupoleCurrents -restoreString 1} result] {
    APSSetVarAndUpdate status "GetSextupoleSettings: $result"
} else {
    set restoreSextupolesString [lindex $result 0]
    set I(S1) [lindex $result 1]
    set I(S2) [lindex $result 2]
    set I(S3) [lindex $result 3]
    set I(S4) [lindex $result 4]
}

MakeMainFrame -parent .userFrame

set excitationFile /home/helios/oagData/sr/magnets/sext/averageExcitCurves.sdds
set scrFile /home/helios/oagData/SCR/snapshots/SR/SR-UserBeamReference.gz
set lteFile $OAGGlobal(SRLatticesDirectory)/default/aps.lte
set beamline RING
set tmpDir /tmp
set BRhoPVName S:BRhoCALC
set c_mks 0.299792458
#set xrefFile /home/helios/SR/controlFiles/SS_xref.sdds
set xrefFile /home/helios/oagData/sr/magnets/sext/SSP_xref.sdds


# Local Variables:
# mode: tcl
# End:
