#!/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
set args $argv
set boosterAve 1
set boosterSingleTurn 0
set bts 1
set SR 0
set plane ""
set setupBPM 0
set setupInj 0
set restoreOPS 0
set filename ""
set help 0
set cycles 0
set usage "collectInjectionBPMData -booster <1|0> -bts <1|0> -sr <1|0> -plane <x|y|h|v> -setupBPM <1|0> -setupInj <1|0> -restoreOPS <1|0>\nplane is not required for bts, but required for booster/sr bpms.\nsetupInj can be done in the first experiment, restoreOPS should be done in last experiment"

APSParseArguments {boosterAve boosterSingleTurn bts SR plane setupInj setupBPM restoreOPS filename help cycles}

if $help {
    puts $usage
    exit 0
}

proc SetMainStatus {text} {
    puts $text
}

proc SetupSRBPM {args} {
    set  SRInjMode continuous
    APSParseArguments {SRInjMode}
    
    switch $SRInjMode {
        continuous {
            if [catch {exec cavput -list=Mt:SRinjectMaxCyclesAO.VAL=1000,Mt:SRinjectModeBO.VAL=1 -pend=10 
                exec cavput -list=S40,S1,S2 -list=A,B -list=:singleTurn:AutoRestart=1 -pend=10 
                exec cavput -list=S40,S1,S2 -list=A,B -list=:singleTurn:Enable=1 -pend=10
                exec cavput -list=S40,S1,S2 -list=A,B -list=:clientEvent2d.OUT1=0 
                exec cavput -list=S40,S1,S2 -list=A,B -list=:clientEvent2d.OUT0=1 } result] {
                return -code error "Error setup sr bpm: $result"
            }
        }
        single {
            if [catch {exec cavput -list=Mt:SRinjectMaxCyclesAO.VAL=1,Mt:SRinjectModeBO.VAL=1 -pend=10 
                exec cavput -list=S40,S1,S2 -list=A,B -list=:singleTurn:AutoRestart=0 -pend=10 
                exec cavput -list=S40,S1,S2 -list=A,B -list=:singleTurn:Enable=1 -pend=10
                exec cavput -list=S40,S1,S2 -list=A,B -list=:clientEvent2d.OUT1=1 
                exec cavput -list=S40,S1,S2 -list=A,B -list=:clientEvent2d.OUT0=0 } result] {
                return -code error "Error setup sr bpm: $result"
            }
        }
    }
}

proc SetupOnAxis {args} {
    set normal 0
    set IK3 7.44
    set IK4 10
    set AH2 -14.95
    set AH1 -0.07
    APSParseArguments {normal IK3 IK4 AH1 AH2} 
    
    if !$normal {
        if [catch {exec cavget -list=S-DCCT:CurrentM -pend=30 -printErrors } current] {
            return -code error "Error reading SR current: $current!"
        }
        if {$current>0.5} {
            return -code error "There is stored beam in the ring, please dump it first!"
        }
        SetMainStatus "setup on-axis... waiting 20 seconds, please be patient..."
        exec cavput -pend=20 -list=Mt:SRinjectZeroBucketsBO=1,Mt:SRinjectBunchCntCC.VAL=0 
        exec cavput -pend=20 -list=S:IK3:VoltageSetSendAO=8.4,S:IK4:VoltageSetSendAO=12
        exec cavput -list=S39A:H1,S39A:H2 -list=:ControlSrcBO=Maintenance
        after 1000
        exec cavput -list=S39A:H2:CurrentAO=100,S39A:H1:CurrentAO=100
        after 10000
       # after 20000
       # exec cavput -list=S39A:H1,S39A:H2 -list=:ControlSrcBO=Operation
    } else {
        SetMainStatus "setup normal operation...."
        exec cavput -pend=20  -list=S:IK3:VoltageSetSendAO=$IK3,S:IK4:VoltageSetSendAO=$IK4
        exec cavput -list=S39A:H1,S39A:H2 -list=:ControlSrcBO=Maintenance
        after 1000
        exec cavput -list=S39A:H2:CurrentAO=$AH2,S39A:H1:CurrentAO=$AH1
        after 10000
        exec cavput -list=S39A:H1,S39A:H2 -list=:ControlSrcBO=Operation
    }
    SetMainStatus "done."
}

proc RestoreOpsState {args} {
    set SRInjMode continuous
    APSParseArguments {SRInjMode}
    foreach PV {S:IK3:VoltageSetSendAO S:IK4:VoltageSetSendAO S39A:H2:CurrentAO S39A:H1:CurrentAO} \
      name {IK3 IK4 AH2 AH1} {
          if [catch {exec sddsprocess /home/helios/oagData/SCR/snapshots/SR/SR-UserBeamPreferred.gz -pipe=out \
                       -match=col,ControlName=$PV \
                       | sdds2stream -pipe=in -col=ValueString } result] {
              return -code error "Error reading IK3 for UBOP: $result"
          }
          set $name $result
      }
    if {$SRInjMode=="continuous"} {
        SetMainStatus "Stop injection..."
        if [catch {exec cavput -list=Mt:SRinjectMultiStopBO.VAL=1 -pend=30} result] {
            SetMainStatus "Error stop injection: $result"
        }
        if [catch {exec cavput -list=Mt:SRinjectMaxCyclesAO.VAL=1 -pend=30} result] {
            SetMainStatus "Error changing max. injection cycles to 1: $result"
        }
    }
    if [catch {SetupOnAxis -normal 1 -IK3 $IK3 -IK4 $IK4 -AH1 $AH1 -AH2 $AH2} result] {
        return -coe error "Error restore normal ops: $result"
    }
}


set srRamFile ""
set boosterRamFile ""
set monFileList ""

if {$SR || $boosterSingleTurn} {
    if ![string length $plane] {
        puts stderr "Error: plane not provided for sr/booster bpms!"
        exit 1
    }
    set pl [string to lower $plane]
    switch $pl {
        x -
        h {
            set plane H
            set coord X
        }
        y -
        v {
            set plane V
            set coord Y
        }
        default {
            puts stderr "Invalid plane provided!"
            exit 1
        }
    }
    if $SR {
        lappend monFileList /home/helios/oagData/BTS/responseMeasurement/Sbpm.meas.$plane
    }
    if $boosterSingleTurn {
        lappend monFileList /home/helios/oagData/booster/responseMeasFiles/${plane}.singleTurnBPM
    }
}
if $boosterAve {
    #need arm non single turn booster bpms
   # exec /home/oxygen/SHANG/oag/apps/src/tcltkapp/oagapp/armBBPMs -all 1 -event 45
    lappend monFileList /home/helios/oagData/booster/responseMeasFiles/region9.mon
}
if $bts {
    lappend monFileList /home/helios/oagData/BTS/responseMeasurement/BTSall.mon
}

if $setupInj {
    if $SR {
        puts "Setup injection..."
        if [catch {SetupOnAxis} result] {
            puts stderr "Error setup injection: $result"
            exit 1
        }
        puts "done."
    }
}
if $setupBPM {
    if $SR {
        set dir /home/helios/oagData/SCR/snapshots/SBPMWaveform
        set ramFile $dir/SBPMWaveform-single${coord}BTS.gz
        set filename [file readlink $ramFile]
        if [catch {exec sddscasr $filename -restore -pendIOTime=60 \
                     -waveform=directory=$dir,onefile,rootname=[file rootname [file tail $filename]],extension=.waveform.gz } result] {
            puts stderr "Error loading SR single turn ram file: $result"
            exit 1
        }
    }
    if $booster {
        set dir /home/helios/oagData/SCR/snapshots/BBPMWaveform/
        set ramFile $dir/BBPMWaveform-singleTurnX.gz
        set filename [file readlink $ramFile]
        if [catch {exec sddscasr $filename -restore -pendIOTime=60 \
                     -waveform=directory=$dir,onefile,rootname=[file rootname [file tail $filename]],extension=.waveform.gz } result] {
            puts stderr "Error loading booster single turn  ram file: $result"
            exit 1
        }
    }
}

if ![llength $monFileList] {
    if $restoreOPS {
        if [catch {RestoreOpsState} result] {
            puts stderr "Error restore operation: $result"
            exit 1
        }
    }
    #do not collect data
    exit 0
}

if ![string length $filename] {
    set filename [clock format [clock seconds] -format %Y-%m%d-%H%M%S.sdds]
}
set monFile [file rootname $filename].mon
if [llength $monFileList]==1 {
    exec cp $monFileList $monFile
} else {
    if [catch {eval exec sddscombine $monFileList -merge $monFile -over} result] {
        puts stderr "Error create mon file: $result"
        exit 1
    }
}
#collecting data during topup
set pvList {Mt:TopUpTime2Inject.VAL Mt:TopUpAutoEnableC.VAL}
set varList {injTime topup}
pv linkw $varList $pvList
pv getw $varList

set count 0
if {$topup!="Enable"} {
    puts stderr "Non topup mode"
    #exit 1
    
} else {

    while {1} {
        if {$cycles && $count>$cycles} {
            break
        }
        pv getw $varList
        if {$topup!="Enable"} {
            puts stderr "Not in topup mode, exit!"
            exit 1
        }
        puts "waiting for injecting..."
        while {$injTime>=6} {
            pv getw $varList
            if {$topup!="Enable"} {
                puts stderr "Not in topup mode, exit!"
                exit 1
            }
            after 1000
        }
       # APSWaitWithUpdate -waitSeconds 4 -updateInterval 1
      #  APSWaitWithUpdate -waitTime 
        puts "collecting data..."
        exec sddsmonitor $monFile $filename -append -time=10,seconds -interval=0.5,seconds
        incr count
    }
}
exit 0
