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

# $Log: not supported by cvs2svn $
# Revision 1.3  2008/03/17 18:00:55  shang
# added tekdpo6 scope and changed the timeout to 200 seconds for waiting scope to be triggered.
#
# Revision 1.2  2008/03/17 14:41:56  soliday
# Modified so that it checks to see if we are in topup user operation mode
# before setting up the scope.
#
# Revision 1.1  2008/03/14 19:51:49  shang
# first version for archiving beam loss data
#
#originally wrote by CY, modified by Shang


# name of scope and PV prefix
# PV name = prefix + pvRoot
# scope     prefix
# tekdpo1   S:BM:los1 
# tekdpo2   S:BM:curr
# tekdpo5   p0fbk 
# tekdpo6   S:BM:los2

set args $argv
set scopename ""
set channelList ""
set waitForTrigger 0
set usage "beamLossMonitorLogger -scopename <scope name> -channelList <list of channel IDs>"
APSParseArguments {scopename channelList waitForTrigger}


proc SetupScope {args} {
    set scope ""
    set channelList ""
    APSParseArguments {scope channelList}
    
    foreach channel $channelList {
        if [catch {exec cavput -list=${scope}:chan${channel}EnableBO=1 } result] {
            return -code error"SetupScope(1): Unable to enable the channel: $result"
        }
    }
    if [catch {exec cavget -list=${scope}:GPIBenableBO -num} scopeEnabled] {
        return -code error "SetupScope(3): Unable to read ${scope}:GPIBenableBO : $scopeEnabled"
    }
    if $scopeEnabled {
        if [catch {exec cavput -list=${scope}:GPIBenableBO=0} result] {
            return -code error "SetupScope(4): Unable to disable scope GPIB: $result"
        }
    }
    if [catch {exec cavput -list=${scope}:fileFormatMO=0 } result] {
        return -code error "SetupScope(5): Unable to set ${scope}:fileFormatMO : $result"
    }
    #set up for single sequence
    if [catch {exec cavput -list=${scope}:singleSeqBO=1 } result] {
        return -code error "SetupScope(6): unable to set up single sequece: $result" 
    }
}

proc CheckSRStatus {args} {
    if [catch {exec cavget -list=S:ActualMode -num } srbeam] {
        return -code error "Unable to read S:ActualMode: $srbeam"
    }
    if {$srbeam!=4} {
        return 0
    }
    if [catch {exec cavget -list=Mt:TopUpAutoEnableC.VAL -num} topup] {
        return -code error "Unable to read Mt:TopUpAutoEnableC.VAL: $topup"
    }
    if {!$topup} {
        return 0
    }
    return 1
}

proc SaveData {args} {
    set scope ""
    set scopename ""
    set channelList ""
    set timeout 200
    set waitForTrigger 1
    APSParseArguments {scope channelList scopename waitForTrigger}
    #arm the trigger
    global scopeDir logDir
    
    if [catch {exec cavput  -list=${scope}:runBO=1 } result] {
        return -code error "SaveData(1): unable to arm the trigger: $result"
    }
    if $waitForTrigger {   
        set t0 [expr [clock seconds]+$timeout]
        while {[clock seconds]<$t0} {
            if [catch {exec cavget -list=${scope}:acquireStatBI} stat] {
                return -code error "SaveData(2 - error in reading ${scope}:acquireStatBI): $stat"
            }
            # test to make sure the scope is armed. 
            if { $stat == "RUNNING" } {
                break
            }
            after 500
        }
        if [catch {exec cavget -list=${scope}:acquireStatBI} stat] {
            return -code error "SaveData(3 - error in reading ${scope}:acquireStatBI): $stat"
        }
        # test to make sure the scope is armed. 
        if [string compare $stat "RUNNING"]!=0 {
            return -code error "SaveData(4): the scope was not running after triggered $timeout seconds."
        }
        set t0 [expr [clock seconds] + $timeout]
        # test to see whether the scope is triggered.
        while {[clock seconds]<$t0} {
            if [catch {exec cavget -list=${scope}:acquireStatBI } stat] {
                puts stderr "SaveData(5 - error in reading ${scope}:acquireStatBI): $stat"
                exit 1
            }
            if { $stat == "STOP" } {
                break
            }
            after 1000
        }
        if [catch {exec cavget -list=${scope}:acquireStatBI} stat] {
            return -code error "SaveData(6 - error in reading ${scope}:acquireStatBI): $stat"
        }
        if [string compare $stat "STOP"]!=0 {
            return -code error "SaveData(7): the scope did not stop after running for $timeout seconds."
        }
    }
    #save data
    set suffix [clock format [clock seconds] -format %Y-%m%d-%H%M%S]
    foreach channel $channelList {
        set buffFileRoot ${channel}-$suffix
        if [catch {exec cavput -list=${scope}:WrFileCh${channel}SO=\"H:\\${scopename}\\traces\\$buffFileRoot\" -pend=10} result] {
            return -code error "SaveData(8 - cavput -list=${scope}:WrFileCh${channel}SO=\"H:\\${scopename}\\traces\\$buffFileRoot\"): $result"
        }
    }
   
    foreach channel $channelList {
        set buffFileRoot ${channel}-$suffix
        set filename $logDir/ch${channel}-$suffix
        set filename0 ${scopeDir}/$scopename/traces/${buffFileRoot}.wfm
        set timeout [expr [clock seconds] + 5]
        while {[clock seconds]<$timeout} {
            if [file exist $filename0] {
                break
            }
            after 500
        }
        if ![file exist $filename0] {
            return -code error "$filename0 was not generated!"
        }
        if [catch {exec wfm2sdds $filename0 $filename -float} result] {
            return -code error "SaveData(9 -- unable to move scope data to SDDS): $result"
        }
        catch {file delete -force ${scopeDir}/$scopename/traces/${buffFileRoot}.wfm}
    }
}

set logDir /home/helios/oagData/sr/beamLoss/$scopename
set scopeDir /net/oxygen/pcfiles/pc/scopeusr_share

switch $scopename {
    tekdpo1 {
        set scope S:BM:los1 
    }
    tekdpo2 {
        set scope S:BM:curr
    }
    tekdpo5 { 
        set scope p0fbk
    }
    tekdpo6 {
        set scope S:BM:los2
    } 
    default {
        puts stderr "getScopeTrace(1): wrong scope name: $scopename"
        exit 1
    }
}

#check sr status, only take data in topup user operation
if [catch {CheckSRStatus} stat] {
    puts stderr "Error in check SR status: $stat"
    exit 1
}
if !$stat {
    puts "beam loss data can only be taken during topup user operation."
    exit 0
}

if [catch {SetupScope -scope $scope -channelList $channelList} result] {
    puts stderr "Unable to setup scope: $result"
    exit 1
}

#save data
if [catch {SaveData -scope $scope -channelList $channelList -scopename $scopename -waitForTrigger $waitForTrigger} result] {
    puts stderr "Unable to save scope data: $result"
    exit 1
}

exit 0
