
proc APSCollectDPCorrectorHistoryInfo {args} {
   return "This procedure downloads all datapool corrector histories, combines them into columns of one file."
}

proc APSCollectDPCorrectorHistory {args} {
    set filename ""
    APSStrictParseArguments {filename}
    
    # Loop over correctors in each sector.

    for {set corr 1} {$corr < 5} {incr corr} {
        # The A corrector will be read by the first waveform
        # The B corrector will be read by the second waveform
        for {set sector 1} {$sector < 41} {incr sector} {
            set PVa  DP:S${sector}HCorrHistorySel1P=S${sector}A:H$corr
            set PVb  DP:S${sector}HCorrHistorySel2P=S${sector}B:H$corr
            lappend PVlist $PVa $PVb
            set PVa  DP:S${sector}VCorrHistorySel1P=S${sector}A:V$corr
            set PVb  DP:S${sector}VCorrHistorySel2P=S${sector}B:V$corr
            lappend PVlist $PVa $PVb
        }
        if [catch {exec cavput -list=[join $PVlist ,] \
                     -pend=15 } result] {
            return -code error "APSCollectDPCorrectorHistory(1): $result"
        }

        # update waveform records before collecting data
        if [catch {exec cavput -list=DP:S -range=beg=1,end=40 \
                     -list=H,V \
                     -list=CorrHistory -list=1,2 -list=SU=1 \
                     -pend=15 } result] {
            return -code error "APSCollectDPCorrectorHistory(2): $result"
        }
        exec sleep 1

        # waveform name must be changed to correctors.
        # corrector name is in DP:S1HCorrHistorySel1P.VAL
        # corrector waveform is in DP:S1HCorrHistory1WF.VAL
        if [catch {exec sddswmonitor \
                     /home/helios/oagData/mpsDumps/inputs/DPCorrectors${corr}.wmon \
                     $filename.$corr} status] {
            return -code error "APSCollectDPCorrectorHistory(3): $status"
        }
    }
    # update waveform records before collecting data
    if [catch {exec cavput -list=DP: -list=H,V -list=CorrHistoryTsSU.PROC=1 \
                 -pend=15 } result] {
        return -code error "APSCollectDPCorrectorHistory(2): $result"
    }
    if [catch {exec sddswmonitor \
                 /home/helios/oagData/mpsDumps/inputs/DPTimeStamps.wmon \
                 $filename.times \
                 -precision=double} status] {
        return -code error "APSCollectDPCorrectorHistory(3): $status"
    }
    
    exec sddsxref $filename.1 $filename.2 $filename.3 $filename.4 -pipe=out \
      | sddsxref -pipe=in $filename.times $filename.5 \
      -take=HTimeStamps,VTimeStamps
    #add the time difference in seconds between EPICS time and VXWorks time
    #vxwork starts from 1990, while EPICS starts from 1970, need add 20 years in seconds
    #this difference is defined in epics/base/include/drvTS.h TS_VXWORKS_TO_EPICS_EPOCH
    set timediff 631152000
    if [catch {exec sddsprocess $filename.5 $filename \
                 "-redef=col,HTimeStamps,HTimeStamps $timediff +" \
                 "-redef=col,VTimeStamps,VTimeStamps $timediff +" } result] {
        return -code error $result
    }
    file delete $filename.1 $filename.2 $filename.3 $filename.4 $filename.times $filename.5
}

proc APSCollectVideoWaveform {args} {
    set filename ""
    APSStrictParseArguments {filename}
    if [catch {exec sddswmonitor \
                 /home/helios/oagData/mpsDumps/inputs/VideoWaveforms.wmon \
                 $filename.data \
             } status] {
        return -code error "APSCollectVideoWaveform(0): $status"
    }
    if [catch {exec sddswmonitor \
                 /home/helios/oagData/mpsDumps/inputs/VideoTimeStamps.wmon \
                 $filename.times \
                 -precision=double} status] {
        return -code error "APSCollectVideoWaveform(1): $status"
    }
    exec sddsxref $filename.data $filename.times $filename \
      -take=TimeStamps
    file delete $filename.data $filename.times
}


proc APSCollectInUseDPCorrectorHistory {args} {
    set filename ""
    APSStrictParseArguments {filename}
    
    if [catch {APScagetTextFromWaveform -pvName DP:S:OrbitControlLawXSDDS.OPTN} xoption] {
        return -code error "APSCollectInUseDPCorrectorHistory(1): $xoption"
    }
    set xoption [split $xoption " "]
    foreach item $xoption {
        # check for option
        if ![regexp {^\-} $item] {
            # it's the matrix!
            set xconfig [file dir $item]
            break
        }
    }

    if [catch {APScagetTextFromWaveform -pvName DP:S:OrbitControlLawYSDDS.OPTN} yoption] {
        return -code error "APSCollectInUseDPCorrectorHistory(2): $yoption"
    }
    set yoption [split $yoption " "]
    foreach item $yoption {
        # check for option
        if ![regexp {^\-} $item] {
            # it's the matrix!
            set yconfig [file dir $item]
            break
        }
    }
    set yconfig [file dir [lindex $yoption 1]]
    set tmpRoot /tmp/[APSTmpString]
    if [catch {exec sddsprocess $xconfig/config -match=par,NameType=CorrectorNames -pipe=out \
                   -edit=col,Name1,Name,Z: \
                   | sddsprocess -pipe -scan=col,corrector,Name1,H%ld,type=long -scan=col,Sector,Name,S%ld,type=long \
                   | sddssort -pipe -col=corrector \
                   | sddsbreak -pipe -changeof=corrector \
                   | sddsprocess -pipe -process=corrector,first,Corr \
                   | sddscast -pipe=in -cast=par,Corr,double,long $tmpRoot.x
        exec sddsprocess $yconfig/config -match=par,NameType=CorrectorNames  -pipe=out \
                   -edit=col,Name1,Name,Z: \
                   | sddsprocess -pipe -scan=col,corrector,Name1,V%ld,type=long -scan=col,Sector,Name,S%ld,type=long \
                   | sddssort -pipe -col=corrector  \
                   | sddsbreak -pipe -changeof=corrector \
                   | sddsprocess -pipe -process=corrector,first,Corr \
                   | sddscast -pipe=in -cast=par,Corr,double,long $tmpRoot.y } result] {
        return -code error "APSCollectInUseDPCorrectorHistory(3): $result"
    }
    set xcorrList [exec sdds2stream $tmpRoot.x -par=Corr]
    set ycorrList [exec sdds2stream $tmpRoot.y -par=Corr]
    set fileList ""
    for {set corr 1} {$corr < 5} {incr corr} {
        # The A corrector will be read by the first waveform
        # The B corrector will be read by the second waveform
        set PVlist ""
        set xindex [lsearch $xcorrList $corr]
        set yindex [lsearch $ycorrList $corr]
        if {$xindex<0 && $yindex<0} {
            continue
        }
        if {$xindex>=0} {
            set sectorList [exec sdds2stream -col=Sector $tmpRoot.x -page=[expr $xindex +1]]
            set nameList [exec sdds2stream -col=Name $tmpRoot.x -page=[expr $xindex +1]]
            foreach sector $sectorList name $nameList {
                if [regexp {A:H} $name] {
                    lappend PVlist DP:S${sector}HCorrHistorySel1P=$name
                } elseif [regexp {B:H} $name] {
                    lappend PVlist DP:S${sector}HCorrHistorySel2P=$name
                }
            }
        }
        if {$yindex>=0} {
            set sectorList [exec sdds2stream -col=Sector $tmpRoot.y -page=[expr $yindex +1]]
            set nameList [exec sdds2stream -col=Name $tmpRoot.y -page=[expr $yindex +1]]
            foreach sector $sectorList name $nameList {
                if [regexp {A:V} $name] {
                    lappend PVlist DP:S${sector}VCorrHistorySel1P=$name
                } elseif [regexp {B:V} $name] {
                    lappend PVlist DP:S${sector}VCorrHistorySel2P=$name
                }
            }
        }
        if [catch {exec cavput -list=[join $PVlist ,] \
                       -pend=15 } result] {
            return -code error "APSCollectInUseDPCorrectorHistory(4): $result"
        }
        
        # update waveform records before collecting data
        if [catch {exec cavput -list=DP:S -range=beg=1,end=40 \
                       -list=H,V \
                       -list=CorrHistory -list=1,2 -list=SU=1 \
                       -pend=15 } result] {
            return -code error "APSCollectInUseDPCorrectorHistory(5): $result"
        }
        exec sleep 1
        # waveform name must be changed to correctors.
        # corrector name is in DP:S1HCorrHistorySel1P.VAL
        # corrector waveform is in DP:S1HCorrHistory1WF.VAL
        if [catch {exec sddswmonitor \
                       /home/helios/oagData/mpsDumps/inputs/DPCorrectors${corr}.wmon \
                       $filename.$corr} status] {
            return -code error "APSCollectInUseDPCorrectorHistory(6): $status"
        }
        lappend fileList $filename.$corr
    }
    # update waveform records before collecting data
    if [catch {exec cavput -list=DP: -list=H,V -list=CorrHistoryTsSU.PROC=1 \
                   -pend=15 } result] {
        return -code error "APSCollectInUseDPCorrectorHistory(7): $result"
    }
    if [catch {exec sddswmonitor \
                   /home/helios/oagData/mpsDumps/inputs/DPTimeStamps.wmon \
                   $filename.times \
                   -precision=double} status] {
        return -code error "APSCollectInUseCorrectorHistory(8): $status"
    }
    
    if [catch {eval exec sddsxref $fileList -pipe=out \
                   | sddsxref -pipe=in $filename.times $filename.5 -nowarnings \
                   -take=HTimeStamps,VTimeStamps } result] {
        return -code error "APSCollectInUseDPCorrectorHistory(9): $result"
    }
    #add the time difference in seconds between EPICS time and VXWorks time
    #vxwork starts from 1990, while EPICS starts from 1970, need add 20 years in seconds
    #this difference is defined in epics/base/include/drvTS.h TS_VXWORKS_TO_EPICS_EPOCH
    set timediff 631152000
    if [catch {exec sddsprocess $filename.5 $filename \
                 "-redef=col,HTimeStamps,HTimeStamps $timediff +" \
                 "-redef=col,VTimeStamps,VTimeStamps $timediff +" } result] {
        return -code error "APSCollectInUseDPCorrectorHistory(10): $result"
    }
    eval file delete -force $fileList
    file delete $filename.times $filename.5
}

proc APSCollectDPBPMs {args} {
    set rootname ""
    APSStrictParseArguments {rootname}
    foreach coord {x y} {
        if [catch {exec sddswmonitor \
                     /home/helios/oagData/mpsDumps/inputs/DPbpms.$coord.wmon \
                     $rootname.$coord } status] {
            return -code error "APSCollectDPBPMs(1): $status"
        }
    }
}
