#!/bin/sh  
# \
exec oagtclsh "$0" "$@"

#Input Files:  /home/helios/oagData/sr/BPMStatus/config.sdds
#              /home/helios/oagData/monitoring/IDs/IDs.mon
#              /home/helios/oagData/monitoring/BMs/BMs.mon
#              /home/helios/oagData/logging/srBPMAve/extraPVs.mon
#
#Output Files: /home/helios/oagData/logging/srBPMAve/srBPMAve.mon

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 rootname srBPMAve
set root $rootname
set usage {usage: makeSRBPMAveInputFile [-output <filename> | -install 1]}
set output ""
set install 0
set args $argv
if {[APSStrictParseArguments {output install}] || \
      (![string length $output] && !$install) || \
      ([string length $output] && $install)} {
    puts stderr "Error for $argv0 in [pwd]: $usage"
    exit 1
}

if !$install {
    if [file exists $output] {
        puts stderr "Error for $argv0 in [pwd]: $output exists"
        exit 1
    }
} else {
    set lastFile [lindex [lsort [glob ${rootname}.mon-????]] end]
    set output [APSNextGenerationedName -name $lastFile -newFile 1]
    set newFile $output
}


#set fid [sdds open $output.tmp w]
#sdds defineColumn $fid ControlName -type SDDS_STRING
#sdds defineColumn $fid ReadbackName -type SDDS_STRING
#sdds defineColumn $fid ReadbackUnits -type SDDS_STRING
#sdds writeLayout $fid
# 40 sectors
# 22 possible bpms
# 13 control points
#sdds startPage $fid [expr 40*22*13]

set data(ColumnNames) "ControlName ReadbackName ReadbackUnits"
set data(ColumnInfo.ControlName) "type SDDS_STRING"
set data(ColumnInfo.ReadbackName) "type SDDS_STRING"
set data(ColumnInfo.ReadbackUnits) "type SDDS_STRING"
set ControlName ""
set ReadbackName ""
set ReadbackUnits ""
set CNxSuffixList {:x:LowPass1sAdjustedM :x:LowPass8sAdjustedM :x:LowPass64sAdjustedM 
                   :x:LowPass1sErrorM :x:LowPass8sErrorM :x:LowPass64sErrorM 
                   :x:SampledM :x:SampledAdjustedM :x:SampledErrorM 
                   :x :x:ErrorM :x:AdjustedM :x:PositionM 
                   :x:SetpointC :x:OffsetM :x:OffsetC :x:GainC}
set RNxSuffixList {:x:LowPass1sAdjustedM :x:LowPass8sAdjustedM :x:LowPass64sAdjustedM 
                   :x:LowPass1sErrorM :x:LowPass8sErrorM :x:LowPass64sErrorM 
                   :x:SampledM :x:SampledAdjustedM :x:SampledErrorM 
                   :x :x:ErrorM :x:AdjustedM :x:PositionM 
                   :x:SetpointC :x:OffsetM :x:OffsetC :x:GainC}
set CNySuffixList {:y:LowPass1sAdjustedM :y:LowPass8sAdjustedM :y:LowPass64sAdjustedM 
                   :y:LowPass1sErrorM :y:LowPass8sErrorM :y:LowPass64sErrorM 
                   :y:SampledM :y:SampledAdjustedM :y:SampledErrorM 
                   :y :y:ErrorM :y:AdjustedM :y:PositionM 
                   :y:SetpointC :y:OffsetM :y:OffsetC :y:GainC}
set RNySuffixList {:y:LowPass1sAdjustedM :y:LowPass8sAdjustedM :y:LowPass64sAdjustedM 
                   :y:LowPass1sErrorM :y:LowPass8sErrorM :y:LowPass64sErrorM 
                   :y:SampledM :y:SampledAdjustedM :y:SampledErrorM 
                   :y :y:ErrorM :y:AdjustedM :y:PositionM 
                   :y:SetpointC :y:OffsetM :y:OffsetC :y:GainC}
set UnitsList {mm mm mm 
    mm mm mm 
    "" "" "" 
    "" "" "" mm 
    mm mm mm ""}
#set CNxSuffixList {:msAve:AveEnbBO :mswAve:sx :mswAve:x :mswAvePn:x :mswAvePw:x 
#                   :mswAve:x:ErrorCC :ms:x:SetpointAO :ms:x:OffsetAO :mswAve:x:AdjustedCC}
#set RNxSuffixList {AveDisabled :mswAve:sx :mswAve:x :mswAvePn:x :mswAvePw:x 
#                   :mswAve:x:ErrorCC :ms:x:SetpointAO :ms:x:OffsetAO :mswAve:x:AdjustedCC}
#set CNySuffixList {:msAve:AveEnbBO :mswAve:sy :mswAve:y :mswAvePn:y :mswAvePw:y 
#                   :mswAve:y:ErrorCC :ms:y:SetpointAO :ms:y:OffsetAO :mswAve:y:AdjustedCC}
#set RNySuffixList {AveDisabled :mswAve:sy :mswAve:y :mswAvePn:y :mswAvePw:y 
#                   :mswAve:y:ErrorCC :ms:y:SetpointAO :ms:y:OffsetAO :mswAve:y:AdjustedCC}
#set UnitsList {"" mm mm mm mm mm mm mm mm}
#set P0CNSuffixList {:wAve:agc :wAve:sum}
#set P0RNSuffixList {:wAve:agc :wAve:sum}
#set P0UnitsList {"" ""}
#set IDxCNSuffixList {:ms:x:GainAO}
#set IDxRNSuffixList {:ms:x:GainAO}
#set IDxUnitsList {""}
#set IDyCNSuffixList {:ms:y:GainAO}
#set IDyRNSuffixList {:ms:y:GainAO}
#set IDyUnitsList {""}
#set SectorCNSuffixList {:mswAve:CoeffAO :msAve:Num2AveAO}
#set SectorRNSuffixList {:mswAve:CoeffAO :msAve:Num2AveAO}
#set SectorUnitsList {"" ""}

proc GetIOCSector {args} {
    APSParseArguments {sector bpmType}
    switch $bpmType {
        P0 {
            #  odd/even arrangment
            if {1==[expr $sector%2]} {
                return $sector
            } else {
                return [expr $sector - 1]
            }
        }
        Xray {
            #  odd/even arrangment for sectors below 32
            #  even/odd arrangment for sectors 32 and above
            if { $sector < 32 } {
                if {1==[expr $sector%2]} {
                    return $sector
                } else {
                    return [expr $sector - 1]
                }
            } else {
                if {1==[expr $sector%2]} {
                    return $sector
                } else {
                    return [expr $sector + 1]
                }
            }
        }
    }
    return $sector
}

# x plane
set dataDir /home/helios/oagData/sr/BPMStatus
if [catch {exec sddsprocess $dataDir/config.sdds -pipe=out \
             -filter=col,NonexistentH,0,0,OkForLoggingH,1,1,& \
             | sdds2stream -col=DeviceName -pipe \
         } xBPMs] {
    puts stderr "Error for $argv0 in [pwd]: $xBPMs"
    exit 1
}
if [catch {exec sddsprocess $dataDir/config.sdds -pipe=out \
             -filter=col,NonexistentV,0,0,OkForLoggingV,1,1,& \
             | sdds2stream -col=DeviceName -pipe \
         } yBPMs] {
    puts stderr "Error for $argv0 in [pwd]: $yBPMs"
    exit 1
}

set extraNbBPMList [exec sddsprocess $dataDir/config.sdds \
                      -pipe=out -match=col,ElectronicsType=Narrowband \
                      -noWarnings | sdds2stream -pipe -col=DeviceName]

foreach bpm [lsort $xBPMs] {
    set items [llength $CNxSuffixList]
    for {set index 0} {$index<$items} {incr index} {
        lappend ControlName ${bpm}[lindex $CNxSuffixList $index]
        lappend ReadbackName ${bpm}[lindex $RNxSuffixList $index]
        lappend ReadbackUnits [lindex $UnitsList $index]
    }
    if {0} {
    if {[lsearch $extraNbBPMList $bpm] > -1} {
        set items [llength $P0CNSuffixList]
        for {set index 0} {$index<$items} {incr index} {
            lappend ControlName ${bpm}[lindex $P0CNSuffixList $index]
            lappend ReadbackName ${bpm}[lindex $P0RNSuffixList $index]
            lappend ReadbackUnits [lindex $P0UnitsList $index]
        }
        regexp {S(.*).:P(.)} $bpm {} sector digit
        set sector [GetIOCSector -sector $sector -bpmType P0]
        set items [llength $SectorCNSuffixList]
        for {set index 0} {$index<$items} {incr index} {
            lappend ControlName S:bpm${sector}P0[lindex $SectorCNSuffixList $index]
            lappend ReadbackName S:bpm${sector}P0[lindex $SectorRNSuffixList $index]
            lappend ReadbackUnits [lindex $SectorUnitsList $index]
        }
    }
    if [regexp ID $bpm] {
        set items [llength $IDxCNSuffixList]
        for {set index 0} {$index<$items} {incr index} {
            lappend ControlName ${bpm}[lindex $IDxCNSuffixList $index]
            lappend ReadbackName ${bpm}[lindex $IDxRNSuffixList $index]
            lappend ReadbackUnits [lindex $IDxUnitsList $index]
        }
        regexp {S(.*)ID} $bpm {} sector
        set sector [GetIOCSector -sector $sector -bpmType Xray]
        set items [llength $SectorCNSuffixList]
        for {set index 0} {$index<$items} {incr index} {
            lappend ControlName S:bpm${sector}Xray[lindex $SectorCNSuffixList $index]
            lappend ReadbackName S:bpm${sector}Xray[lindex $SectorRNSuffixList $index]
            lappend ReadbackUnits [lindex $SectorUnitsList $index]
        }
    }
    }
}
foreach bpm [lsort $yBPMs] {
    set items [llength $CNySuffixList]
    for {set index 0} {$index<$items} {incr index} {
        lappend ControlName ${bpm}[lindex $CNySuffixList $index]
        lappend ReadbackName ${bpm}[lindex $RNySuffixList $index]
        lappend ReadbackUnits [lindex $UnitsList $index]
    }
    if {0} {
    if {[lsearch $extraNbBPMList $bpm] > -1} {
        set items [llength $P0CNSuffixList]
        for {set index 0} {$index<$items} {incr index} {
            lappend ControlName ${bpm}[lindex $P0CNSuffixList $index]
            lappend ReadbackName ${bpm}[lindex $P0RNSuffixList $index]
            lappend ReadbackUnits [lindex $P0UnitsList $index]
        }
        regexp {S(.*).:P(.)} $bpm {} sector digit
        set sector [GetIOCSector -sector $sector -bpmType P0]
        set items [llength $SectorCNSuffixList]
        for {set index 0} {$index<$items} {incr index} {
            lappend ControlName S:bpm${sector}P0[lindex $SectorCNSuffixList $index]
            lappend ReadbackName S:bpm${sector}P0[lindex $SectorRNSuffixList $index]
            lappend ReadbackUnits [lindex $SectorUnitsList $index]
        }
    }
    if [regexp ID $bpm] {
        set items [llength $IDyCNSuffixList]
        for {set index 0} {$index<$items} {incr index} {
            lappend ControlName ${bpm}[lindex $IDyCNSuffixList $index]
            lappend ReadbackName ${bpm}[lindex $IDyRNSuffixList $index]
            lappend ReadbackUnits [lindex $IDyUnitsList $index]
        }
        regexp {S(.*)ID} $bpm {} sector
        set sector [GetIOCSector -sector $sector -bpmType Xray]
        set items [llength $SectorCNSuffixList]
        for {set index 0} {$index<$items} {incr index} {
            lappend ControlName S:bpm${sector}Xray[lindex $SectorCNSuffixList $index]
            lappend ReadbackName S:bpm${sector}Xray[lindex $SectorRNSuffixList $index]
            lappend ReadbackUnits [lindex $SectorUnitsList $index]
        }
    }
    }
}

for {set i 1} {$i <= 40} {incr i} {
    set ii [format %02d $i]
    foreach p1 {"A:" "B:" "ID:" ":" "-FLB:" "-IES:" "-TFB:" "-DCCT" "-LFB:"} {
        foreach p2 {"P0:" "P1:" "P2:" "P3:" "P4:" "P5:" "P6:" "GV1:" "VC14:" "VC16:" "DLMA:" "FODO:" "CA1:" "VC:TC1:" "VC:TC2:" "VC:TC3:" "VC:TC4:" "DLMB:" "KICK1:" "KICK2:" "KICK_H:" "KICK_V:" "DK0:" "IK1:" "IK2:" "IK3:" "IS1:" "CT1:" "CT2:"} {
            foreach p3 {"" "TC1:" "TC2:" "TC3:" "TC4:" "TC5:" "TC6:" "TC7:" "TC8:" "TC1_1:" "TC1_2:" "TC2_1:" "TC2_2:" "TC3_1:" "TC3_2:" "TC4_1:" "TC4_2:" "IR1:" "IR2:"} {
                foreach p4 {TemperatureM CalibTemperatureM PlinthTemperatureM PlinthCalibTemperatureM AirTemperatureM AirCalibTemperatureM} {
                    lappend ControlName S${ii}${p1}${p2}${p3}${p4}
                    lappend ReadbackName S${ii}${p1}${p2}${p3}${p4}
                    lappend ReadbackUnits C
                }
            }
        }
    }
    foreach p1 {"CAP" "HS" "RTD"} {
        foreach p2 {"AP0" "BP0" "GRID" "GRID2" "UpstreamAir" "DownstreamAir"} {
            foreach p3 {x y disp diff chamber floor} {
                lappend ControlName ${p1}:S${ii}:${p2}:${p3}
                lappend ReadbackName ${p1}:S${ii}:${p2}:${p3}
                lappend ReadbackUnits ""
            }
            lappend ControlName ${p1}:S${ii}:${p2}
            lappend ReadbackName ${p1}:S${ii}:${p2}
            lappend ReadbackUnits ""
        }
        lappend ControlName ${p1}:S${ii}:diff
        lappend ReadbackName ${p1}:S${ii}:diff
        lappend ReadbackUnits ""
    }
    lappend ControlName S${ii}:RackTemp:InsideHigh
    lappend ReadbackName S${ii}:RackTemp:InsideHigh
    lappend ReadbackUnits C
    lappend ControlName S${ii}:RackTemp:InsideLow
    lappend ReadbackName S${ii}:RackTemp:InsideLow
    lappend ReadbackUnits C
    lappend ControlName S${ii}:RackTemp:InsideMid
    lappend ReadbackName S${ii}:RackTemp:InsideMid
    lappend ReadbackUnits C
    lappend ControlName S${ii}:RackTemp:OutsideAmbient
    lappend ReadbackName S${ii}:RackTemp:OutsideAmbient
    lappend ReadbackUnits C


}
for {set i 38} {$i <= 39} {incr i} {
    foreach p1 {"-FLB:" "-IES:" "-TFB:"} {
        foreach p2 {"KICK1:" "KICK2:" "DK0:" "KICK_V:" "KICK_H:" "IK1:" "IK2:" "IK3:" } {
            foreach p3 {"TC1_1:" "TC1_2:" "TC2_1:" "TC2_2:" "TC3_1:" "TC3_2:" "TC4_1:" "TC4_2:" "TC1:" "TC2:" "TC3:" "TC4:" "TC5:" "TC6:" "IR1:" "IR2:"} {
                foreach p4 {TemperatureM CalibTemperature_} {
                    lappend ControlName S${i}${p1}${p2}${p3}${p4}
                    lappend ReadbackName S${i}${p1}${p2}${p3}${p4}
                    lappend ReadbackUnits C
                }
            }
        }
    }
}




set data(Column.ControlName) [list $ControlName]
set data(Column.ReadbackName) [list $ReadbackName]
set data(Column.ReadbackUnits) [list $ReadbackUnits]
sdds save $output.tmp data
#eval sdds setColumn $fid ControlName $ControlName
#eval sdds setColumn $fid ReadbackName $ReadbackName
#eval sdds setColumn $fid ReadbackUnits $ReadbackUnits
#sdds writePage $fid
#sdds close $fid

if {[catch {exec sddsprocess $output.tmp -print=column,Provider,ca -print=column,ExpectNumeric,y,type=character -print=column,ExpectFieldType,scalar -define=column,ExpectElements,1,type=long -nowarn} results]} {
    puts "ERROR: $results"
    exit
}
# insert PVs from the IDs monitor file: source points, gap.
# Assume that the IDs.mon has been created first, which is
# usually the order in which files are created 
# (see file /home/helios/oagData/sr/startupScripts/config.sdds)

exec sddsprocess /home/helios/oagData/monitoring/IDs/IDs.mon IDsSet.mon \
    -match=col,ControlName=S*:ID:SrcPt:*,ControlName=*:Gap*,|
#same for BM
exec sddsprocess /home/helios/oagData/monitoring/BMs/BMs.mon BMsSet.mon \
    -match=col,ControlName=S*:BM:SrcPt:*,ControlName=S*BM:VPOSITION:CC,|,ControlName=S*BM:VANGLE:CC,|

# remove duplicate control names when combining x and y names
set recordFile /home/helios/oagData/pvdata/iocRecNamesOAG.sdds
exec sddscombine $output.tmp /home/helios/oagData/logging/srBPMAve/extraPVs.mon IDsSet.mon BMsSet.mon -pipe=out \
  -merge \
  | sddssort -pipe \
  -col=ControlName -unique \
  | sddsprocess -pipe \
  -edit=col,rec_name,ControlName,S?/./D \
  | sddsxref -pipe $recordFile -match=rec_name -nowarning -reuse \
  | sddsconvert -pipe -delete=col,rec_name \
  | sddsprocess -pipe=in $output \
  -reprint=column,ControlType,pv -reprint=column,ControlMode,RO

file delete $output.tmp $output.tmp~

if $install {
    puts stderr "New  file: [exec sdds2stream -rows $newFile]"
    
    if [string length $lastFile] {
        exec sddsselect $newFile $lastFile PVsAdded -match=ControlName -invert
        exec sddsselect $lastFile $newFile PVsRemoved -match=ControlName -invert
        puts stderr "Last file: [exec sdds2stream -rows $lastFile]"
        puts stderr "PVs added: [exec sdds2stream -rows PVsAdded]"
        puts stderr "PVs removed: [exec sdds2stream -rows PVsRemoved]"
    }
    if [file exists ${root}.mon] {
        file delete ${root}.mon
    }
    exec ln -s $newFile $rootname.mon
}

exit
