#!/bin/sh
# \
exec oagtclsh "$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)]
APSStandardSetup

#
# $Log: not supported by cvs2svn $
# Revision 1.2  2006/09/21 20:39:58  soliday
# Updated because of PV name changes.
#
# Revision 1.1  2002/06/03 09:12:43  borland
# First version.
#
#

set usage \
{usage:  corrOrbit -rootname <calculated-Response-File> -processor <scdu | ms> -plane <x | y> -gain <number> [-SVs <number>] [-numToAve <orbitsToAve>] [-excludeBPMs <commaSepList>] [-excludeCorrs <commaSepList>] [-despike {0|1}]}

set rootname booster
set processor ms
set plane y
set SVs 10
set numToAve 30
set excludeBPMs ""
set excludeCorrs ""
set gain 0.5
set args $argv

if {[APSStrictParseArguments {rootname processor plane gain SVs numToAve excludeBPMs excludeCorrs}] \
    || ![string length $rootname] || ![string length $processor] \
    || ![string length $processor] || $SVs<1 || $numToAve<2 } {
    puts stderr $usage
    puts stderr ""
    puts stderr "-rootname  - Rootname of file to put raw and fit data."
    puts stderr "-processor - bpm processor electronics scdu | ms."
    puts stderr "-plane     - x | y"
    return 0
}

proc setTiming {args} {
    return 0

    set N 0
    set M 256

    APSStrictParseArguments {N M}
    catch {exec cavput -list=B:bpmT1_8:Delay_count_lo=${N},B:bpmT9_16:Delay_count_lo=${N},B:bpmT17_24:Delay_count_lo=${N},B:bpmT25_32:Delay_count_lo=${N},B:bpmT33_40:Delay_count_lo=${N},B:bpmT41_48:Delay_count_lo=${N},B:bpmT45_46:Delay_count_lo=${N},B:bpmT49_56:Delay_count_lo=${N},B:bpmT57_64:Delay_count_lo=${N},B:bpmT65_72:Delay_count_lo=${N},B:bpmT73_80:Delay_count_lo=${N} -pendIoTime=20}

    catch {exec cavput -list=B:bpmT1_8:Cycle_count_lo=${M},B:bpmT9_16:Cycle_count_lo=${M},B:bpmT17_24:Cycle_count_lo=${M},B:bpmT25_32:Cycle_count_lo=${M},B:bpmT33_40:Cycle_count_lo=${M},B:bpmT41_48:Cycle_count_lo=${M},B:bpmT45_46:Cycle_count_lo=${M},B:bpmT49_56:Cycle_count_lo=${M},B:bpmT57_64:Cycle_count_lo=${M},B:bpmT65_72:Cycle_count_lo=${M},B:bpmT73_80:Cycle_count_lo=${M} -pendIoTime=20}
    return 0
}


# Create inverse matrix file:

if [string compare $plane x]==0 {
    set suffix hrm
    # T-m/A
    set calib 0.00136
} else {
    set suffix vrm
    # T-m/A
    set calib 0.00113
}

set matrix ${rootname}.$suffix
if [catch {exec sddsquery $matrix -sddsOutput -column \
    | sddsprocess -pipe -match=col,Name=B?C?? \
        -match=col,Units=m/rad,! -nowarning \
    | sdds2stream -rows=bare -pipe} result] {
    return -code error "$result"
}
if $result!=0 {
    return -code error "Units wrong in matrix: need m/rad from elegant ($result)"
}
if [string length $excludeBPMs] {
    exec sddstranspose ${rootname}.$suffix -pipe=out \
    | sddsconvert -pipe -delete=column,$excludeBPMs \
    | sddstranspose -pipe=in ${rootname}.$suffix.tmp \
    -oldColumnNames=BPMName
    set matrix ${rootname}.$suffix.tmp
    APSAddToTempFileList ${rootname}.$suffix.tmp
} 

if [string length $excludeCorrs] {
    set excludeCorrs $excludeCorrs,B4C9IK,B2C8EK
} else {
    set excludeCorrs B4C9IK,B2C8EK
}

exec sddsconvert -pipe=out $matrix \
  "-delete=col,s,$excludeCorrs" \
  | sddspseudoinverse -pipe=in ${rootname}.i${suffix} \
  -oldColumnNames=ControlName -largestSingularValues=$SVs

foreach Set {1 2} N {3400 44679} Energy {450 7000} {
    # Get Orbit for a given N
    setTiming -N $N -M 256
    after 2000
    puts "Set N=${N}"

    exec sddsconvert $matrix -retain=col,BPMName -pipe=out  \
      | sddsprocess -pipe \
      -print=col,ControlName,%s:$processor:$plane:ErrorCC,BPMName \
      | sddssnapshot -pipe \
      -average=$numToAve,0.5 -nameOfData=$plane -unitsOfData=mm  \
      | sddsconvert -pipe -retain=col,ControlName,$plane \
      | sddsprocess -pipe=in Bbpm_${plane}_${N}.sdds \
      -match=column,ControlName=*:${processor}:${plane}* \
      "-redefine=param,M,256" \
      "-redefine=param,N,${N}" \
      "-redefine=column,$plane,$plane 1000 /,units=m" 
    puts "Got data"

    # Multiply the inverse response matrix by the vector of bpm values
    exec sddsmatrixmult ${rootname}.i${suffix} Bbpm_${plane}_${N}.sdds -pipe=out \
      | sddsprocess -pipe \
        "-define=col,Value,$plane $Energy 299.79 / * $calib / 19 / $gain * -1 *,units=A/19" \
      | sddsconvert -pipe -delete=col,$plane \
      | sddsxref -pipe -take=ControlName ${rootname}.i${suffix} \
      | sddsprocess -pipe=in Cor_${plane}_${N}.sdds \
        -match=col,ControlName=etax,! 
    exec sddsplot "-title=[clock format [clock seconds]]  $rootname" \
      -col=ControlName,*$plane Bbpm_${plane}_${N}.sdds -end \
      -column=ControlName,Value Cor_${plane}_${N}.sdds &
    if [catch {sdds load Cor_${plane}_${N}.sdds data$Set} result] {
        return -code error "$result"
    }
    APSAddToTempFileList Bbpm_${plane}_${N}.sdds Cor_${plane}_${N}.sdds
}

set corrList [lindex $data1(Column.ControlName) 0]
set value1List [lindex $data1(Column.Value) 0]
set value2List [lindex $data2(Column.Value) 0]
unset data1 data2

set output(ParameterNames) "ControlName ControlType RampBias CorrName CorrCurrentAO"
set output(ParameterInfo.ControlName) "type SDDS_STRING"
set output(ParameterInfo.ControlType) "type SDDS_STRING"
set output(ParameterInfo.RampBias) "type SDDS_DOUBLE"
set output(ParameterInfo.CorrName) "type SDDS_STRING"
set output(ParameterInfo.CorrCurrentAO) "type SDDS_STRING"
set output(ColumnNames) "RampTime RampSetpoint"
set output(ColumnInfo.RampTime) "type SDDS_DOUBLE"
set output(ColumnInfo.RampSetpoint) "type SDDS_DOUBLE"

foreach corr $corrList value1 $value1List value2 $value2List {
    lappend ControlNameData ${corr}:rampRAMPTABLE
    lappend ControlTypeData pv
    lappend RampBiasData 0.0
    lappend CorrNameData $corr
    lappend CorrCurrentAOData $corr:CurrentAO

    lappend RampTimeData [list 0 15.2 233.2 236.4396 250]
    set RampSetpointList 0
    lappend RampSetpointList $value1
    lappend RampSetpointList $value2
    set endValue [expr ($value2-$value1*1.0)/(233.2-15.2)*(236.4396-233.2)+$value2]
    lappend RampSetpointList $endValue $endValue
    lappend RampSetpointData $RampSetpointList
}
set output(Parameter.ControlName) $ControlNameData
set output(Parameter.ControlType) $ControlTypeData
set output(Parameter.RampBias) $RampBiasData
set output(Parameter.CorrName) $CorrNameData
set output(Parameter.CorrCurrentAO) $CorrCurrentAOData
set output(Column.RampTime) $RampTimeData
set output(Column.RampSetpoint) $RampSetpointData

if [catch {sdds save $rootname.$plane.deltaRamp output} result] {
    return -code error "$result"
}
set lastRampFile [lindex [lsort [glob -nocomplain $rootname.$plane.ramp.????]] end]
if ![string length $lastRampFile] {
    set matchOpt ""
    foreach corr $corrList {
        if ![string length $matchOpt] {
            set matchOpt -match=parameter,CorrName=$corr
        } else {
            set matchOpt $matchOpt,CorrName=$corr,|
        }
    }
    exec sddsprocess /home/helios/oagData/booster/ramps/correctors/HVCorr.ramp \
      $matchOpt -pipe=out \
      | sddssort -pipe=in $rootname.$plane.ramp.0000 -parameter=CorrName 
    set lastRampFile $rootname.$plane.ramp.0000
}
set newFile [APSNextGenerationedName -name $lastRampFile -newFile 1 -separator .]
exec sddssort $rootname.$plane.deltaRamp -pipe=out -parameter=CorrName \
  | sddsconvert -pipe -rename=col,RampSetpoint=DeltaRampSetpoint \
  | sddsxref $lastRampFile -pipe -take=RampSetpoint \
  | sddsprocess -pipe=in $newFile \
  "-redefine=column,RampSetpoint,RampSetpoint DeltaRampSetpoint +" \
  "-description=text=Corrector ramps,contents=booster ramp" 
puts "Made $newFile"
