#!/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.10  2006/11/15 04:45:52  emery
# Replace in the Corrector monitor file the currentAO PV
# with DacAI PVs. The Dac data is more accurate.
#
# Revision 1.9  2006/06/07 19:37:28  shang
# modified making IDcorrectedPVs.mon proc, it now includes all existing blade PVs; modified IDcorrectedPVs.mon.template which now includes all possible blade PVs.
#
# Revision 1.8  2006/01/24 16:06:29  shang
# now cross-check IDcorrectedPVs.mon with iocRecNames.sdds and sort the files
# by ControlName with numericHigh
#
# Revision 1.7  2005/11/09 00:17:25  shang
# now sorted by sector and ControlName.
#
# Revision 1.6  2005/07/05 20:00:12  emery
# Added comments.
#
# Revision 1.5  2005/01/20 18:42:21  emery
# Change some directories/home/helios/oagData/monitoring/<..> to
# /home/helios/oagData/monitoring/<..> because the softlinks
# from the latter to the former don't exist anymore.
#
# Revision 1.4  2004/06/22 19:15:14  emery
# Added filtering such that the CU magnets PVs are plain
# PVs and not the SFB PVs.
#
# Revision 1.3  2004/06/16 15:47:06  emery
# Somehow the recent changes to IDs.mon file included the whole
# file from the source, which contained a large number of unnecessary PVs
# for the gap scan. IDs.mon is now trimmed to the essential.
#
# Revision 1.2  2004/06/15 23:30:33  emery
# Added filtering of IDs.mon PV through the standard iocRecNames.sdds file.
# Retain only P1, P0 errorCC PVs and ID:P1 and ID:P2 raw PVs for bpm files.
#
# Revision 1.1  2004/06/09 19:07:10  emery
# First installation of a script that used to be
# /home/helios/oagData/sr/gapScans/feedforwardInputFiles/makeMonitorFile.
#
# Creates several monitor files derived from existing monitor files
# in official areas.

proc processFile {args} {
    set input ""
    set filterList *
    set excludeList ""
    set originalList ""
    set replacementList ""
    set append ""
    set prepend ""
    set output ""
    APSStrictParseArguments {input excludeList filterList output originalList replacementList append prepend}

    if [file exists $output] {
        return -code error "$output exists already"
    }
    set matchOpt ""
    foreach filter $filterList {
        if ![string length $matchOpt] {
            set matchOpt -match=column,ControlName=$filter
        } else {
            set matchOpt $matchOpt,ControlName=$filter,|
        }
    }
    set optList $matchOpt

    set matchOpt1 ""
    foreach filter $excludeList {
        if ![string length $matchOpt1] {
            set matchOpt1 -match=column,ControlName=$filter,!
        } else {
            set matchOpt1 $matchOpt1,ControlName=$filter,!,&
        }
    }
    if [string length $matchOpt1] {
        lappend optList $matchOpt1
    }

    foreach orig $originalList repl $replacementList {
        lappend optList -reedit=column,ControlName,%/$orig/$repl/
        lappend optList -reedit=column,ReadbackName,%/$orig/$repl/
    }
    if [string length $append] {
        lappend optList "-reedit=col,ControlName,i/$append/"
        lappend optList "-reedit=col,ReadbackName,i/$append/"
    }
    if [string length $prepend] {
        lappend optList "-reedit=col,ControlName,i/$prepend/"
        lappend optList "-reedit=col,ReadbackName,i/$prepend/"
    }
    if [catch {eval exec sddsprocess $input $output $optList} result] {
        return -code error $result
    }
}

proc MakeIDCorrectedPVsMonitorFile {} {
    set configFile /home/helios/oagData/sr/BPMStatus/config.sdds
    set template IDcorrectedPVs.mon.template
    set newFile [APSNextGenerationedName -name IDcorrectedPVs.mon-0001 -separator - -newFile 1]
    if {[file exist IDcorrectedPVs.mon]} {
        set lastFile [file readlink IDcorrectedPVs.mon]
    } else {
        set lastFile ""
    }
    set tmpRoot /tmp/[APSTmpString]
    if [catch {exec sddsprocess $configFile -match=col,DeviceName=S*ID:P* $tmpRoot.config \
                   -filter=col,NonexistentH,0,0,NonexistentV,0,0,& \
                   -scan=col,Sector,DeviceName,S%ld,type=long  } result] {
        return -code error $result
    }
    set sectors [exec sdds2stream /home/helios/oagData/sr/IDs/sectors.sdds -col=Sector]
    set fileList ""
    foreach sector $sectors {
        set sectorf [format %02ld $sector]
        if [catch {exec sddsprocess IDcorrectedPVs.mon.template $tmpRoot.$sector.corrected \
                       -reedit=col,ReadbackName,%/<sectorf>/$sectorf/%/<sector>/$sector/ \
                       -reedit=col,ControlName,%/<sectorf>/$sectorf/%/<sector>/$sector/  } result] {
            return -code error $result
        }
        lappend fileList $tmpRoot.$sector.corrected
    }
    set recordFile /home/helios/oagData/pvdata/iocRecNamesOAG.sdds
    APSAddToTmpFileList -ID makeGapScanFiles -fileList "$tmpRoot.config"
    APSAddToTmpFileList -ID makeGapScanFiles -fileList $fileList
    if [catch {eval exec sddscombine $fileList  -pipe=out -merge \
                   | sddsprocess -pipe -edit=col,rec_name,ControlName,S?/./D \
                   -edit=col,DeviceName,ControlName,%/:CorrectedM//%/:A//%/:B//%/:C//%/:D//%/:E//%/:F// \
                   | sddsxref -pipe $recordFile -leave=* \
                   -reuse -nowarnings -match=rec_name \
                   | sddsselect -pipe $tmpRoot.config -match=DeviceName -reuse \
                   | sddsconvert -pipe -del=col,DeviceName \
                   | sddssort -pipe=in $newFile -col=ControlName -numericHigh } result] {
        return -code error $result
    }
    file delete -force IDcorrectedPVs.mon
    exec ln -s $newFile IDcorrectedPVs.mon
    if [string length $lastFile] {
        if [catch {CheckNewFile -lastFile $lastFile -newFile IDcorrectedPVs.mon} result] {
            puts stderr $result
        }
    }
}
proc MakeIDMonitorFile {} {
    global verbose
    # make the ID monitor file
    set sourceFile /home/helios/oagData/monitoring/IDs/IDs.mon
    set recordFile /home/helios/oagData/pvdata/iocRecNamesOAG.sdds
    set tmpfile /tmp/[APSTmpString]
    
    if {[file exist IDs.mon]} {
        set lastFile [file readlink IDs.mon]
    } else {
        set lastFile ""
    }
    set newFile [APSNextGenerationedName -name IDs.mon-0001 -newFile 1]
    # contents of old script makeIDsMeasurementFile
    # I'm not sure why the upstream linear encoders are included.
    #APSAddToTmpFileList -ID makegapscanfile -fileList "$tmpfile.USLinearEncoder $tmpfile.ID $tmpfile.USMotor"
    if [catch {exec sddsprocess $sourceFile -pipe=out \
                   -match=col,ControlName=*:Gap \
                   | tee $tmpfile.ID \
                   | sddsprocess -pipe=in $tmpfile.USLinearEncoder \
                   -reedit=col,ControlName,%/Gap/USLinearEncoder.VAL/ \
                   -reedit=col,ReadbackName,%/AverageGap/USLinearEncoder/} result] {
        return -code error $result
    }
    
    if [catch {exec sddsprocess $tmpfile.ID $tmpfile.USMotor \
                   -reedit=col,ControlName,%/Gap/USMotor.VAL/ \
                   -reedit=col,ReadbackName,%/AverageGap/USGap/ } result] {
        return -code error $result
    }
    
    # USLinearEncoder and USMotor do not exist for all sectors.
    if [catch {exec sddscombine $tmpfile.ID $tmpfile.USLinearEncoder $tmpfile.USMotor \
                   -pipe=out -merge \
                   | sddsprocess -pipe \
                   -edit=col,rec_name,ControlName,S?/./D \
                   | sddssort -column=rec_name -pipe \
                   | sddsxref -reuse -nowarnings -pipe $recordFile -match=rec_name \
                   | sddsconvert -pipe -delete=col,rec_name \
                   | sddssort -pipe=in $newFile -column=ControlName -numericHigh -unique } result] {
        return -code error $result
    }
    
    if $verbose {
        puts stderr "IDs.mon -> $newFile"
    }
    file delete -force IDs.mon
    exec ln -s $newFile IDs.mon
    if [string length $lastFile] {
        if [catch {CheckNewFile -lastFile $lastFile -newFile IDs.mon} result] {
            puts stderr $result
        }
    }
}

proc CheckNewFile {args} {
    set lastFile ""
    set newFile ""
    APSParseArguments {lastFile newFile}
    set tmpfile /tmp/[APSTmpString]
    APSAddToTmpFileList -ID gapscan -fileList "$tmpfile.old $tmpfile.new"
    if [catch {exec sddsconvert $lastFile -del=par,* -pipe=out \
                 | sddssort -col=ControlName -pipe=in $tmpfile.old} result] {
        return -code error $result
    }
    if [catch {exec sddsconvert $newFile -del=par,* -pipe=out \
                 | sddssort -col=ControlName -pipe=in $tmpfile.new} result] {
        return -code error $result
    }
    if [catch {exec sddsdiff $tmpfile.new $tmpfile.old} results] {
        return -code error "New $newFile differs from last file $lastFile."
    }
}
proc MakeBPMFile {args} {
    global verbose
    set type ms
    APSStrictParseArguments {type}
    
    set newFile [APSNextGenerationedName -name  SR_$type.mon-0001 -separator - -newFile 1]
    if {[file exists SR_$type.mon]} {
        set lastFile [file readlink SR_$type.mon]
    } else {
        set lastFile ""
    }
    set tmpFile /tmp/[APSTmpString]
    if [catch { processFile -input /home/helios/oagData/logging/srBPMs/srBPMs.mon \
                    -output $tmpFile.errorCC \
                    -filterList "[APSMakeSafeQualifierString {S*[ABC]:P[01]*ErrorCC}]" \
                    -originalList ms -replacementList $type } result] {
        return -code error $result
    }
    if [catch {processFile -input /home/helios/oagData/logging/srBPMs/srBPMs.mon \
                   -output $tmpFile.IDbpm \
                   -filterList "[APSMakeSafeQualifierString {S*ID:P[12]*[xy]}]" \
                   -originalList ms -replacementList $type} result] {
        return -code error $result
    }
    if [catch {exec sddscombine $tmpFile.errorCC $tmpFile.IDbpm -pipe=out -merge \
                   | sddssort -pipe=in $newFile -numericHigh -col=ControlName } result] {
        return -code error "MakeBPMFile: $result"
    }
    if $verbose {
        puts stderr "SR_$type.mon -> $newFile"
    }
    file delete -force SR_$type.mon
    exec ln -s $newFile SR_$type.mon
    if [string length $lastFile] {
        if [catch {CheckNewFile -lastFile $lastFile -newFile SR_$type.mon} result] {
            puts stderr $result
        }
    }
}

proc MakeCorrectorFile {} {
    global verbose
    
    set newFile [APSNextGenerationedName -name SR_HVCurrentAO.mon-0001 -separator - -newFile 1]
    if [file exists SR_HVCurrentAO.mon] {
        set lastFile [file readlink SR_HVCurrentAO.mon]
    }  else {
        set lastFile ""
    }
    set tmpFile /tmp/[APSTmpString]
    
    # We want DacAI instead of CurrentAO because DacAI is updated
    # more accurately when datapool is running
    if [catch {processFile -input /home/helios/oagData/logging/SRDCPS-HVD/SRDCPS-HVD.mon \
                   -output $tmpFile.reg -filterList *:CurrentAI  -append "" \
                   -excludeList "*BM* *MT* *C:*" \
                   -originalList CurrentAI -replacementList DacAI} result] {
        return -code error $result
    }
    
    if [catch {processFile -input /home/helios/oagData/logging/SRDCPS-HVD/SRDCPS-HVD.mon \
                   -output $tmpFile.Cmag  -filterList *C*:CurrentAI -append "" \
                   -originalList CurrentAI -replacementList DacAI} result] {
        return -code error $result
    }
    
    if [catch {exec sddscombine $tmpFile.reg $tmpFile.Cmag $newFile -merge} result] {
        return -code error $result
    }
    
    if $verbose {
        puts stderr "SR_HVCurrentAO.mon  -> $newFile"
    }
    file delete -force SR_HVCurrentAO.mon 
    exec ln -s $newFile SR_HVCurrentAO.mon
    if [string length $lastFile] {
        if [catch {CheckNewFile -lastFile $lastFile -newFile SR_HVCurrentAO.mon} result] {
            puts stderr $result
        }
    }
}

proc MakeBriefScanFile {args} {
    set deviceList [exec sdds2stream -col=DeviceName /home/helios/oagData/sr/IDs/devices.sdds]
    set newFile [APSNextGenerationedName -name gapValuesBrief.sdds-00001  -separator - -newFile 1]
    set option ""
    foreach device $deviceList {
        if {$device=="ID01ds" || $device=="ID06ds"} {
            append option "-col=${device}gap,type=double -data=14,16,18,21,24,28,34 "
        } else {
            append option "-col=${device}gap,type=double -data=20,22.5,25.0,27.5,30.0,32.5,35 "
        }
    }
    if [catch {eval exec sddsmakedataset $newFile $option \
                 -col=Step,type=long -data=1,2,3,4,5,6,7} result] {
        return -code error "Error in generatring brief scan values file: $result"
    }
    exec rm gapValuesBrief.sdds
    exec ln -s $newFile gapValuesBrief.sdds
}

set verbose 0
set args $argv
APSParseArguments {verbose}

# These procedures are expected to run in directory
# /home/helios/oagData/sr/gapScans/feedforwardInputFiles

# Creates file IDs.mon
MakeIDMonitorFile
# creates IDcorrectedPVs.mon
if [catch {MakeIDCorrectedPVsMonitorFile} result] {
    puts stderr "MakeIDCorrectedPVsMonitorFile: $result"
}

# Creates file of type SR_$type.mon
MakeBPMFile -type ms 
MakeBPMFile -type msAve
MakeBPMFile -type mswAve

# Creates file SR_HVCurrentAO.mon
MakeCorrectorFile
MakeIDCorrectedPVsMonitorFile
MakeBriefScanFile
exit
