#!/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 sector 1
set ID ID1
set plane x
set window Both
set logFile ""
set P0L 2.756
set P1L 3.213
set lab 1
set testType offset
set beam Sim
set fastAbort 0
set BPMconfig default
#fastabort only test one point
set outDir [APSGoToDailyDirectory -subdirectory IDValidation]
APSParseArguments {sector ID L plane window logFile outDir testType lab beam fastAbort BPMconfig}

set BPLD(lab) $lab
if {$ID=="Both"} {
    set IDList {ID1 ID2}
} else {
    set IDList $ID
}
set BPLD(BPMconfig) $BPMconfig
if {$sector==1} {
    #for S01, ID1 (which is ID40) does not exist, only ID2 is available for validating
    set IDList ID2
}

if {$plane=="Both"} {
    set planeList {x y}
} else {
    set planeList $plane
}
set BPLD(testType) $testType
set BPLD(planeList) $planeList
set BPLD(IDList) $IDList
set BPLD(beam) $beam
set BPLD(fastAbort) $fastAbort

if {$beam=="Real"} {
    #can only use offset for validation with real beam
    set testType offset
}
		 
if $lab {
    set BPLD(configDir) /home/oxygen/DIAG/apsu/BPLD/BPLD_Config
} else {
    set BPLD(configDir) /home/helios/oagData/sr/BPLD/BPLD_Config
}
source /home/oxygen/SHANG/oag/apps/src/tcltkapp/oagapp/LiberaSyntheticDataSetup.tcl
set liberaList {ioc2sn1bpm1 ioc2sn1bpm2 ioc2sn1bpm3 ioc2sn1bpm4 ioc2snbpm5 ioc2snbpm6 ioc2snbpm7}
set BPLD(plane) $plane

proc ReadBPLDConfig {args} {
    global BPLD lab
    if {$BPLD(BPMconfig)=="default"} {
	set configFile $BPLD(configDir)/IDconfig.sdds
    } else {
	set configFile $BPLD(configDir)/BPLDConfig-ID$BPLD(BPMconfig).sdds
    }
    set tmpRoot /tmp/[APSTmpString]
    puts $tmpRoot
    APSAddToTmpFileList -ID id_bpld -fileList $tmpRoot.1
    foreach ID $BPLD(IDList) {
	exec  $BPLD(configDir)/scripts/generateIDBPLDConfigPointBySector -sector $BPLD(sector) \
	    -id $ID -configDir $BPLD(configDir)
	set IDconfig  $BPLD(configDir)/ID_BPLD_Config.S$BPLD(sectorf)$ID.sdds
	APSAddToTmpFileList -ID idbpld -fileList "$tmpRoot.$ID.x $tmpRoot.$ID.y"
	foreach plane {x y} {
	    if [catch {exec sddsprocess $IDconfig -match=par,plane=$plane $tmpRoot.$ID.$plane } result] {
		return -code error "Error process config file: $result"
	    }
	    set BPLD($ID.${plane}OffsetLimit) [expr 1000.0 * [exec sdds2stream -par=OffsetLimit $tmpRoot.$ID.$plane]]
	    set BPLD($ID.${plane}AngleLimit) [expr 1000.0 * [exec sdds2stream -par=AngleLimit $tmpRoot.$ID.$plane]]
	}
	APSAddToTmpFileList -ID bpld -fileList "$tmpRoot.$ID.x $tmpRoot.$ID.y"
    }
    if [catch {exec sddsprocess $configFile -filter=col,BPLDSector,$BPLD(sector),$BPLD(sector)  $tmpRoot.1} result] {
	return -code error "Error1: $result"
    }
    set bpmList [exec sdds2stream -col=DeviceName $tmpRoot.1]
    set indexList [exec sdds2stream -col=BPLDIndex $tmpRoot.1]
    #read BPM index, and ID distance value from firmware
    foreach ID $BPLD(IDList) {
	if [catch {exec cavget -list=S$BPLD(sectorf)-LMPS:BPLD: -list=$ID \
		       -list=:BPM- -list=XY1,XY2 -list=_idx-SP -pend=20} valList] {
	    return -code error "Error reading $BPLD(sector) $BPLD(IDchoice) bpm index: $valList"
	}
   
	set i1 [lsearch -exact $indexList [lindex $valList 0]]
	set i2 [lsearch -exact $indexList [lindex $valList 1]]
	puts "$i1 $i2 $valList"
	if {$i1<0 || $i2<0} {
	    return -code error "Error: bpm index not found in BPLD config"
	}
	set bpm1 [lindex $bpmList $i1]
	set bpm2 [lindex $bpmList $i2]
	set BPLD($ID.bpm1) $bpm1
	set BPLD($ID.bpm2) $bpm2
	set BPLD($ID.useBPMs) [list $bpm1 $bpm2]
	set type ""
	if [regexp {P0} $bpm1] {
	    set type P0
	} else {
	    set type P1
	}
	if [regexp {P0} $bpm2] {
	    append type P0
	} else {
	    append type P1
	}
	#read ID distance
	if [catch {exec cavget -list=S$BPLD(sectorf)-LMPS:BPLD:$ID -list=:S1,:S2 -list=-SP -pend=10 } valList] {
	    return -code error "Error reading ID L: $valList"
	}
	set BPLD($ID.L1) [lindex $valList 0]
	set BPLD($ID.L2) [lindex $valList 1]
	set BPLD($ID.IDL) [expr $BPLD($ID.L2) - $BPLD($ID.L1)]
	set pointList [join [exec sdds2stream -par=${type}DiamondPoint $tmpRoot.$ID.$BPLD(plane)]]
	puts "$ID points: $pointList"
    
	set offsetLimit [expr $BPLD($ID.$BPLD(plane)OffsetLimit)/1000.0]
	set angleLimit [expr $BPLD($ID.$BPLD(plane)AngleLimit)/1000.0]
	
	set BPLD($ID.IDDiamond.S0.1x) [expr -1.0*$offsetLimit]
	set BPLD($ID.IDDiamond.S0.1x') 0
	set BPLD($ID.IDDiamond.S0.2x) [lindex $pointList 0]
	set BPLD($ID.IDDiamond.S0.2x') [lindex $pointList 1]
	set BPLD($ID.IDDiamond.S0.3x) $offsetLimit
	set BPLD($ID.IDDiamond.S0.3x') 0
	set BPLD($ID.IDDiamond.S0.4x) [expr -1.0 * [lindex $pointList 0]]
	set BPLD($ID.IDDiamond.S0.4x') [expr -1.0 * [lindex $pointList 1]]

	set xList [exec sdds2stream -col=${type}_x $tmpRoot.$ID.$BPLD(plane)]
	set xpList [exec sdds2stream -col=${type}_xp $tmpRoot.$ID.$BPLD(plane)]
	set i 1
	foreach x $xList xp $xpList {
	    set BPLD($ID.IDBoth.S0.${i}x) $x
	    set BPLD($ID.IDBoth.S0.${i}x') $xp 
	    set BPLD($ID.IDBoth.S0.${i}y) $x
	    set BPLD($ID.IDBoth.S0.${i}y') $xp 
	    incr i 
	}
    
	foreach coord {x y} {
	    set BPLD($ID.IDRect.S0.1$coord) [expr -1.0*$offsetLimit]
	    set BPLD($ID.IDRect.S0.1${coord}') $angleLimit
	    set BPLD($ID.IDRect.S0.2${coord}) $offsetLimit
	    set BPLD($ID.IDRect.S0.2${coord}') $angleLimit
	    set BPLD($ID.IDRect.S0.3${coord}) $offsetLimit
	    set BPLD($ID.IDRect.S0.3${coord}') [expr -1.0*$angleLimit]
	    set BPLD($ID.IDRect.S0.4${coord}) [expr -1.0*$offsetLimit]
	    set BPLD($ID.IDRect.S0.4${coord}') [expr -1.0*$angleLimit]
	}
	foreach i {1 2 3 4} {
	    set BPLD($ID.IDDiamond.S0.${i}y) $BPLD($ID.IDDiamond.S0.${i}x)
	    set BPLD($ID.IDDiamond.S0.${i}y') $BPLD($ID.IDDiamond.S0.${i}x')
	}
    
	if $lab {
	    #only S44 libera exist in the lab, need match bpm with S44 libera bpm
	    set liberaList [join [exec sdds2stream -col=LiberaBPM /home/oxygen/DIAG/apsu/BPLD/lab_libera.sdds]]
	    set sbpmList [join [exec sdds2stream -col=S$BPLD(sectorf)BPM /home/oxygen/DIAG/apsu/BPLD/lab_libera.sdds]]
	    set index1 [lsearch -exact $sbpmList $BPLD($ID.bpm1)]
	    set index2 [lsearch -exact $sbpmList $BPLD($ID.bpm2)]
	    if {$index1<0} {
		return -code error "Error: $bpm1 not found for sector $BPLD(sector)"
	    }
	    if {$index2<0} {
		return -code error "Error: $bpm1 not found for sector $BPLD(sector)"
	    }
	    set BPLD($ID.liberaBPM1) [lindex $liberaList $index1]
	    set BPLD($ID.liberaBPM2) [lindex $liberaList $index2]
	} else {
	    set BPLD($ID.liberaBPM1) $BPLD($ID.bpm1)
	    set BPLD($ID.liberaBPM2) $BPLD($ID.bpm2)
	}
    }
}


set BPLD(testType) $testType
set BPLD(window) $window
if {$sector==1} {
    set BPLD(IDchoice) ID2
} else {
    set BPLD(IDchoice) $ID
}
set BPLD(sectorf) [format %02d $sector]
set BPLD(sector) $sector
set BPLD(sector1) $sector
set BPLD(sector2) [expr $sector+1]
set BPLD(fsector1) [format %02d $sector]
set BPLD(fsector2) [format %02d $BPLD(sector2)]
set BPLD(plane) $plane
set BPLD(BPLDNumber) [format %02d $sector]
#window choice: Diamond, Rect, Both
set BPLD(window) $window

#read config now
#ReadBPLDConfig
#puts "ID L1: $BPLD(ID.L1)"
#puts "ID L2: $BPLD(ID.L2)"
#puts "ID L: $BPLD(IDL)"

#read BPLDconfig and limit
ReadBPLDConfig
set bpmList ""
foreach ID $BPLD(IDList) {
    lappend bpmList $BPLD($ID.bpm1)
    lappend bpmList $BPLD($ID.bpm2)
    
}
set BPLD(bpmList) $bpmList
if ![string length $logFile] {
    set mainDir [APSGoToDailyDirectory -subdirectory APSUBPLDValidation]
    set logDir $mainDir
    set BPLD(logDir) $logDir
    
    set stamp [clock format [clock seconds] -format %Y%m%d]
    set BPLD(logFile) $logDir/ID[format %02d ${sector}]-${stamp}.log
} else {
    set BPLD(logFile) $logFile
}
set maxBeamS [exec cavget -list=APSU:MMPS2:MaxSoftBeam-SP -pend=30]
set maxBeamH [exec cavget -list=APSU:MMPS2:Sim:HWmaxBeam-SP -pend=30]
if {$maxBeamS<$maxBeamH} {
    set BPLD(allowedBeam) $maxBeamS
} else {
    set BPLD(alloedBeam) $maxBeamS
}

#userReset S${BPLDNumber}-LMPS:UsrReset-SP
set BPLD(userResetPV) S$BPLD(BPLDNumber)-LMPS:UsrReset-SP
set BPLD(simBeamCurrentPV) APSU:MMPS2:Sim:BeamCurrent-SP
set BPLD(hwBeamLimitPV) APSU:MMPS2:Sim:HWmaxBeam-SP
set BPLD(IDcurrentLimitPV) APSU:MMPS2:ID:Thold-SP
set BPLD(swBeamLimitPV) APSU:MMPS2:MaxSoftBeam-SP
set BPLD(simEnablePV) APSU:MMPS2:BeamSim-SP
set BPLD(beamEnablePV) APSU:MMPS2:CtrlReg0-Cmd.B2
set BPLD(P0CountLimitPV) S$BPLD(BPLDNumber)-LMPS:P0_CntLimit-SP
set BPLD(IDglitchTurnsPV) S$BPLD(BPLDNumber)-LMPS:BPLD:ID-GlitchTurns-SP
set BPLD(ID1.enablePV) S$BPLD(BPLDNumber)-LMPS:BPLD:ID1_Enable-SP
set BPLD(ID2.enablePV) S$BPLD(BPLDNumber)-LMPS:BPLD:ID2_Enable-SP
set BPLD(ID.gapSimPV) S$BPLD(BPLDNumber)-LMPS:ID:GapSim-SP

set BPLD(ID.gapSimClosePV) S$BPLD(BPLDNumber)-LMPS:ID:GapSimClose-SP
set BPLD(BMEnablePV) S$BPLD(BPLDNumber)-LMPS:BPLD:BM_Enable-SP

foreach ID {ID1 ID2} {
    foreach nm {H1 H2 V1 V2} bpm {X1 X2 Y1 Y2} {
	set BPLD($ID.diamond${nm}LimitPV) S$BPLD(BPLDNumber)-LMPS:BPLD:${ID}:AIOL-${nm}-SP
	set BPLD($ID.offset${nm}PV) S$BPLD(BPLDNumber)-LMPS:BPLD:${ID}:AIOR-${nm}-SP
	set BPLD($ID.raw${nm}PV) S$BPLD(BPLDNumber)-LMPS:BPLD:${ID}_${bpm}-I
    }
    foreach plane {H V} {
	set BPLD($ID.rect${plane}OffsetLimitPV) S$BPLD(BPLDNumber)-LMPS:BPLD:${ID}:AIOL-${plane}3-SP
	set BPLD($ID.rect${plane}AgnleLimitPV) S$BPLD(BPLDNumber)-LMPS:BPLD:ID1:AIAL_${plane}-SP
    }
    set BPLD($ID.faultPV) S$BPLD(BPLDNumber)-LMPS:BPLD:${ID}_IL_RegOut-I
}

#ID is fast fault
#set BPLD(main1fastPV) APSU:MMPS1:LMPS:FastAbort-Sts
#set BPLD(main2fastPV) APSU:MMPS2:SMA:Data10-I
#use bit for main2fault pv
set fsector [expr ($sector+1)/2-1] 
set Bit [format %X $fsector]
set BPLD(main2fastPV) APSU:MMPS2:SMA:Data10-I.B$Bit
set BPLD(main1fastPV) APSU:MMPS1:LMPS:FastAbort-Sts.B$Bit

#puts $BPLD(main2fastPV)
set BPLD(linkFaultPV) APSU:MMPS1:LMPS[expr ($sector+1)/2]:Fault-I
set BPLD(localMPSPV) S$BPLD(BPLDNumber)-LMPS:MLinkTXpkt_FS-I
set BPLD(IDfaultPV) S$BPLD(BPLDNumber)-LMPS:MLinkTXpkt_FS-I.B1
set BPLD(ID1faultPV) S$BPLD(BPLDNumber)-LMPS:BPLD:ID1_IL_RegOut-I
set BPLD(ID2faultPV) S$BPLD(BPLDNumber)-LMPS:BPLD:ID2_IL_RegOut-I

set nmList [array names BPLD]
set pvList ""
set varList ""
foreach name $nmList {
    if [regexp "PV" $name] {
	lappend pvList $BPLD($name)
	lappend varList BPLD($name.var)
    }
}

set BPLD(pvList) $pvList
set BPLD(varList) $varList
set BPLD(faultVarList) {BPLD(IDfaultPV.var) BPLD(localMPSPV.var) BPLD(linkFaultPV.var) BPLD(main1fastPV.var)} 
set BPLD(faultPVList) {BPLD(IDfaultPV) BPLD(localMPSPV) BPLD(linkFaultPV.var) BPLD(main1fastPV.var)} 

global errorCode
puts $pvList
#flush
if [pv linkw $varList $pvList 30] {
    puts stderr "Error connecting some pvs"
    exit 1
}


#setup values
set BPLD(userRestPV.var) 1
set BPLD(simBeamCurrentPV.var) 25
set BPLD(IDcurrentLimitPV.var) 2.0
set BPLD(simEnablePV.var) 0
set BPL(beamEnalePV.var) 0

set BPLD(ID.gapSimClosePV.var)  1

foreach ID {ID1 ID2} {
    foreach nm {H1 H2 V1 V2} bpm {X1 X2 Y1 Y2} {
	#offset limit
	set BPLD($ID.diamond${nm}LimitPV.var) 1000
    }
    foreach plane {H V} {
	#offset limit
	set BPLD($ID.rect${plane}OffsetLimitPV.var) 1000
	#angle limit
	set BPLD($ID.rect${plane}AgnleLimitPV.var) 250
    }
}

#main1 and main2 fast fault
#local sector fast fault = [expr ($sector+1)/2]
set fsector [expr ($sector+1)/2]
#main2 fast and slow has 21 bits when there is fault
set BPLD(findex) [expr 21 - $fsector]
#main1 and main2 fast and slow faults findex must be 1

puts "start ID validation for sector $sector $BPLD(IDchoice) IDs..."
#set BPLD(xOffsetLimit) 1000
#set BPLD(yOffsetLimit) 500
proc ClearFaults {args} {
    global BPLD
    
    puts "set ID and BPM offsets to 0..."
    if [catch {APScavput -list=S$BPLD(BPLDNumber) \
		   -list=-LMPS:BPLD:ID -list=1,2 -list=:AIOR- \
		   -list=H,V -list=1,2 -list=-SP=0 -pend=60} result] {
	return -code error "Error set ID bpm offsts to zero: $result"
    }
    if [catch {APScavput -list=S$BPLD(BPLDNumber) \
		   -list=-LMPS:BM_ -list=X,Y -range=begin=1,end=28 -list=_Offset-SP=0 -pend=60} result] {
	return -code error "Error set BM bpm offsets to zero: $result"
    }
    #clear External inputs faults
    if [catch {APScavput -list=S$BPLD(BPLDNumber) -list=-LMPS:CtrlReg0-Cmd=0 -pend=30 } result] {
	return -code error "Error clear ext inputs: $result"
    }
    #disable ID1 and ID2
    if [catch {APScavput -list=S$BPLD(BPLDNumber)-LMPS:BPLD: -list=ID1,ID2 -list=_Enable-SP=0 -pend=20 } result] {
	return -code error "Error disable ID: $result"
    }
    after 5000
    if [catch {APScavput -list=$BPLD(userResetPV)=1 -pend=30 } result] {
	return -code error "Error reset to clear faults: $result"
    }
    after 2000
    puts "check if faults are cleared..."
    if [catch {APScavget -list=$BPLD(localMPSPV) -printErrors -pend=30} fault] {
	return -code error "Error reading local MPS fault: $fault"
    }
    return $fault
}

proc SetupValidation {args} {
    global BPLD
    
   
    puts "Step 0: before start validation, check the local MPS fault, make sure it is zero. if not, fix it first!"
    if [catch {ClearFaults} fault] {
	return -code error "Error clearing faults: $fault"
    }
    if $fault {
	puts "Trying to clear the faults for second time..."
	if [catch {ClearFaults} fault] {
	    return -code error "Error clearing faults for second time: $fault"
	}
    }
	
    set BPLDNumber $BPLD(BPLDNumber)
    set BPLD(userResetPV.var) 1
    set BPLD(simBeamCurrentPV.var) 25
    set BPLD(IDcurrentLimitPV.var) 2
    set BPLD(simEnablePV.var) 0
    set BPLD(beamEnablePV.var) 0
    set BPLD(P0CountLimitPV.var) 100
    set varList {BPLD(simBeamCurrentPV.var) BPLD(IDcurrentLimitPV.var) BPLD(simEnablePV.var) BPLD(beamEnablePV.var)}
    pv putw $varList 30
    set BPLD(userResetPV.var) 1
    pv putw BPLD(userResetPV.var) 30
    after 2000
    puts "Step 0: before start validation, check the local MPS fault, make sure it is zero. if not, fix it first!"
    pv getw BPLD(localMPSPV.var) 30
    update
    set fault $BPLD(localMPSPV.var)
    
    if $fault {
	puts "The local MPS fault for S$BPLD(BPLDNumber) has to be cleared before starting validation!"
	exit 1
    }
    
    puts "To enable BM/ID validation, it needs following conditions"
    puts "1)the simulated hardware limit should be equal or greater than BM engaged current."
    #puts "2) software limit should be less than the hardware limit but greater than BM/ID engaged current."
    puts "2) MPS arming current should be greater than 0 (normally set to 0.5mA)"
    puts "3) beam simulation current has to be equal or greater than BM/ID engaged current."
    puts "checking hardware limit..."
    
    pv getw BPLD(IDcurrentLimitPV.var) 30
    pv getw BPLD(hwBeamCurrentPV.var) 30
    pv getw BPLD(swBeamLimitPV.var) 30
    update
    
    set hwLimit $BPLD(hwBeamLimitPV.var)
    set IDengageCurrent $BPLD(IDcurrentLimitPV.var)
    set limit 0
    if { $hwLimit<[expr $IDengageCurrent+5]} {
	set limit [expr $IDengageCurrent+20]
    }
    if $limit>0 {
	puts "Hardware limit is lower than ID engage current, increase it to $limit"
	set BPLD(simBeamCurrentPV.var) $limit
	set hwLimit $limit
	pv putw BPLD(simBeamLimitPV.var) 30
	
    }
    puts "checking software current limit..."
    set swLimit $BPLD(swBeamLimitPV.var)
    
    set limit 0
    if {$swLimit>$hwLimit} {
	puts "software limit is higher than hardward limit, reduce it."
	set limit [expr $hwLimit - 2]
    }
    
    if {$swLimit<$IDengageCurrent} {
	set limit [expr $IDengageCurrent + 1 ]
	puts "software limit is lower than ID engage current, increase it."
    }
    if {$limit>0} {
#	set BPLD(swBeamLimitPV.var) $limit
#	pv putw BPLD(swBeamLimitPV.var) 30
    }
    puts "checking beam simulation current: it should be equal or greater than BM/ID engaged current"
    pv getw BPLD(simBeamCurrentPV.var) 30
    update
    set beamCurrent $BPLD(simBeamCurrentPV.var)
 
    puts "enable beam simulator"
    switch $BPLD(beam) {
	Sim {
	    set BPLD(simEnablePV.var) 1
	    set BPLD(ID.gapSimPV.var) 1
	    set BPLD(beamEnablePV.var) 0
	}
	Real {
	    set BPLD(simEnablePV.var) 0
	    set BPLD(ID.gapSimPV.var) 0
	    set BPLD(beamEnablePV.var) 1
	}
    }
    pv putw BPLD(simEnablePV.var) 30
    
    #disable BM, ID1, ID2, enable gap sim, and close gap
    set BPLD(BMEnablePV.var) 0
    set BPLD(ID1.enablePV.var) 0
    set BPLD(ID2.enablePV.var) 0
    #gapSim mode should be checked when gap is closed
    set BPLD(ID.gapSimClosePV.var) 1
    set BPLD(userResetPV.var) 1
    set varList {BPLD(BMEnablePV.var) BPLD(ID1.enablePV.var) BPLD(ID2.enablePV.var) BPLD(ID.gapSimPV.var) BPLD(ID.gapSimClosePV.var) BPLD(beamEnablePV.var)}
    pv putw $varList 30
    pv putw BPLD(userResetPV.var) 30
    puts "reset and enable ID"
    
    
    
    set BPLD(simEnablePV.var) 1
    update
    
    puts "S$BPLD(BPLDNumber) ID is ready for validation."
}

proc SetDPBPLDStatus {text} {
    puts $text
    flush stdout
}

#validate IDBPMs with offset

proc ValidateIDBPMs {args} {
    global BPLD
    
    set BPLDNumber $BPLD(BPLDNumber)
    SetDPBPLDStatus "Start ID bpm validation with offset..."
    SetDPBPLDStatus "Disable BPM bpms..."
    set BPLD(startTime) [clock format [clock  seconds] -format %Y%m%d-%H:%M:%S]
    if [catch {APScavput -list=S${BPLDNumber}-LMPS:BPLD:BM_Enable-SP=0 -pend=30 } result] {
	return -code error "Error disable BM status: $result"
    }
    SetDPBPLDStatus "clear faults..."
    if [catch {SetupValidation -type ID} result] {
	return -code error "Error setup ID validation: $result"
    }
    SetDPBPLDStatus "Set BPLD ID BPM window shape..."
    if [catch {APScavput -list=S${BPLDNumber}-LMPS:BPLD:ID-Shape-SP=$BPLD(window) -pend=30} result] {
	return -code error "Error setting ID bpm window shape..."
    }
    
    
    SetDPBPLDStatus "Set beam simulation current to 5..."
    if [catch {APScavput -list=APSU:MMPS2:Sim:BeamCurrent-SP=5 -pend=30} result] {
	return -code error "Error setting beam simulation current: $result"
    }
    SetDPBPLDStatus "Set gap simulation mode to 1"
    if [catch {APScavput -list=S${BPLDNumber}-LMPS:ID:GapSim-SP=1 -pend=30} result] {
	return -code error "Error set gap simulation mode: $result"
    }
    SetDPBPLDStatus "Set simulated gap closed..."
    if [catch {APScavput -list=S${BPLDNumber}-LMPS:ID:GapSimClose-SP=1 -pend=30} result] {
	return -code error "Error set gap close: $result"
    }
    SetDPBPLDStatus "Set ID engaged beam current APSU:MMPS2:ID:Thold-SP – set to threshold current to arm the ID BPM"
    if [catch {APScavput -list=APSU:MMPS2:ID:Thold-SP=$BPLD(IDcurrentLimitPV.var) -pend=30} result] {
	return -code error "Error setting ID beam current limit: $result"
    }
    switch $BPLD(IDchoice) {
	ID1 {
	    set ID1val 1
	    set ID2val 0
	} ID2 {
	    set ID1val 0
	    set ID2val 1
	} 
	default {
	    #both ID
	    set ID1val 1
	    set ID2val 1
	}
    }
    
    if [catch {APScavput -list=S${BPLDNumber}-LMPS:BPLD: -list=ID1,ID2 -list=_Enable-SP=0 -pend=30} result] {
	return -code error "Error disable ID: $result"
    }
    after 1000
    SetDPBPLDStatus "enabling ID..."
    if [catch {APScavput -list=S${BPLDNumber}-LMPS:BPLD:ID1_Enable-SP=$ID1val,S${BPLDNumber}-LMPS:BPLD:ID2_Enable-SP=$ID2val \
		   -pend=30} result] {
	return -code error "Error enable ID check: $result"
    }
    set result0 1
    
    switch $BPLD(plane) {
	both {
	    #only one plane is allowed for validation, so this case should never happen
	    set coordList {x y}
	}
	default {
	    set coordList $BPLD(plane)
	}
    }
    
    #need changed waveform and scalar type to linear mode (instead of Polynormial) for this test
    set sector1 $BPLD(sector1)
    set sector2 $BPLD(sector2)
    if {0} {
	#note that scalar PV: 0: poly 1: linear; datapool, 0: linear, 1: poly
	#can not use string values -- because the IOC does not accept string for these pvs
	if [catch {exec cavput -list=S${sector1}B:P0:ConvertBO.VAL=1,S${sector2}A:P0:ConvertBO.VAL=1,DP:BpmDoPolyC=0 -pend=10} result] {
	    return -code error "Error setting bpm mode: $result"
	}
    }
    set result0 passed
    foreach coord $coordList {
	SetDPBPLDStatus "Validating $coord plane..."
	switch $BPLD(testType) {
	    offset {
		if [catch {ValidateIDBPMWithOffset  -coord $coord} result] {
		    return -code error "Error validating $coord bpm: $result"
		}
	    }
	    synthetic {
		if [catch {ValidateIDBPMWithSyntheticData -coord $coord} result] {
		     return -code error "Error validating $coord bpm with synthetic data: $result"
		}
	    }
	}
	if {$result=="failed"} {
	    set result0 failed
	}
    }
    set BPLD(result) $result0
    set BPLD(endTime)  [clock format [clock  seconds] -format %Y%m%d-%H:%M:%S]
    SetDPBPLDStatus "clearing faults..."
    if [catch {ClearFaults} result] {
	puts "Error clear faults: $result"
    }
    SetDPBPLDStatus "log result..."
    LogIDValidationResult -type offset
    
    ResetIDBPMOffsets
}

proc ValidateIDBPMWithOffset {args} {
    set coord x
    set reset 1
    APSParseArguments {coord reset}

    global BPLD
    set window $BPLD(window)
    
    switch $coord {
	x {
	    set plane H
	}
	y {
	    set plane V
	}
    }
    set Coord [string toupper $coord]
    if {$BPLD(window)=="Rect" || $BPLD(window)=="Diamond"} {
	set points 4
    } else {
	set points 12
    }
    if $BPLD(fastAbort) {
	#fast abort only test one point
	set points 1
    }
    puts "Test points: $points"
    set result0 passed
   
    set win $BPLD(window)
    for {set i 1} {$i<=$points} {incr i} {
	SetDPBPLDStatus "reset offsets..."
	foreach ID $BPLD(IDList) {
	    if [catch {APScavput -list=S$BPLD(BPLDNumber)-LMPS:BPLD:${ID}:AIOR-${plane}1-SP=0,S$BPLD(BPLDNumber)-LMPS:BPLD:${ID}:AIOR-${plane}2-SP=0 -pend=30} result] {
		return -code error "Error setting offset: $result"
	    }
	}
	after 3000
	set BPLD(userResetPV.var) 1
	pv putw BPLD(userResetPV.var) 30
	after 2000
	
	SetDPBPLDStatus "working with contour point - $i..."
	foreach ID $BPLD(IDList) {
	    puts "working on ID: $ID"
	    if [catch {APScavput -list=S$BPLD(BPLDNumber)-LMPS:BPLD:${ID}_Enable-SP=1 -pend=30 } result] {
		return -code error "Error enable $ID: $result"
	    }
	    set s0 [set BPLD($ID.ID$win.S0.${i}$coord)]
	    set sp0 [set BPLD($ID.ID$win.S0.${i}${coord}')]
	    puts "$s0 $sp0  kkk"
	    #for any P0 and P1 combination, use L1 and L2 instead of L
	    set s1 [expr 1.0e3 * ($s0 - abs($BPLD($ID.L1)) * $sp0)]
	    set s2 [expr 1.0e3 * ($s0 + $BPLD($ID.L2)  * $sp0)]
	    puts "$s1 $s2"
	    
	    if [catch {APScavget -list=S$BPLD(BPLDNumber)-LMPS:BPLD:${ID}_${Coord} -list=1,2 -list=-I -printErrors -pend=30 } result] {
		return -code error "Error reading current position: $result"
	    }
	    #increase by 5% to make sure trip
	    set offset1 [expr -1.0 * $s1*1.05 + [lindex $result 0]]
	    set offset2 [expr -1.0 * $s2*1.05 + [lindex $result 0]]
	    puts  "ID=$ID offset1 $offset1, offset2=$offset2"
	    if {!$BPLD(lab) && $BPLD(beam)!="Sim"} {
		#use real setpoint PV to change the setpoint
		if [catch {APScavput -list=$BPLD($ID.bpm1):$BPLD(plane):SetpointC=$offset1,$BPLD($ID.bpm2):$BPLD(plane):SetpointC=$offset2 -pend=10 } result] {
		    return -code error "Error setting setpoint: $result"
		}
		#wait for orbit correction to be done
	#	exec cawait -timeLimit=30 -waitFor=$BPLD($ID.bpm1):$BPLD(plane):LowPass1sErrorM,lowerLimit=-100,upperLimit=100 -waitFor=$BPLD($ID.bpm2):$BPLD(plane):LowPass1sErrorM,lowerLimit=-100,upperLimit=100
	    } else {
		if [catch {APScavput -list=S$BPLD(BPLDNumber)-LMPS:BPLD:${ID}:AIOR-${plane}1-SP=$offset1,S$BPLD(BPLDNumber)-LMPS:BPLD:${ID}:AIOR-${plane}2-SP=$offset2 -pend=30} result] {
		    return -code error "Error setting offset: $result"
		}
	    }
	}
	set BPLD(userResetPV.var) 1
	pv putw BPLD(userResetPV.var) 30
	if {!$BPLD(lab) && $BPLD(beam)!="Sim"} {
	    puts "waiting for OC to converge..."
	  #  eval exec cawait $BPLD(waitFor) -timeLimit=30
	    after 5000
	} else {
	    #after 5000
	    after 10000
	}
	
	set result [CheckIDFaultStatus]
	
	if {$result=="failed"} {
	    set result0 0
	    SetDPBPLDStatus "ID offset validation at ${i}th point failed."
	    break
	} else {
	    SetDPBPLDStatus "ID offset validation at ${i}th point passed."
	}
	if {!$BPLD(lab) && $BPLD(beam)!="Sim"} {
	    SetDPBPLDStatus "reset setpoints (clear faults)..."
	    foreach ID $BPLD(IDList) {
		if [catch {APScavput -list=$BPLD($ID.bpm1),$BPLD($ID.bpm2) -list=:$BPLD(plane):SetpointC=0 -pend=10} result] {
		    return -code error "Error clear setpoint: $result"
		}
	    }
	    after 3000
	    puts "wait for orbit..."
	}
	if {$BPLD(lab)} {
	    SetDPBPLDStatus "reset offsets..."
	    foreach ID $BPLD(IDList) {
		if [catch {APScavput -list=S$BPLD(BPLDNumber)-LMPS:BPLD:${ID}:AIOR-${plane}1-SP=0,S$BPLD(BPLDNumber)-LMPS:BPLD:${ID}:AIOR-${plane}2-SP=0 -pend=30} result] {
		    return -code error "Error setting offset: $result"
		}
	    }
	    after 3000
	    set BPLD(userResetPV.var) 1
	    pv putw BPLD(userResetPV.var) 30
	    after 2000
	}
    }
    set BPLD($ID.$coord.result) $result0
}

proc CheckIDFaultStatus {args} {
    global BPLD
    set BPLDNumber $BPLD(BPLDNumber)
    SetDPBPLDStatus "checking ID bpm fault status..."
    
    if [catch {APScavget -list=$BPLD(IDfaultPV),$BPLD(localMPSPV),$BPLD(linkFaultPV),$BPLD(main1fastPV),$BPLD(main2fastPV),$BPLD(ID1faultPV),$BPLD(ID2faultPV) \
		   -printErrors -pend=30} valList] {
	return -code error "Error reading fault pvs: $valList"
    }
    set BPLD(faultDesc) ""
    set BPLD(IDfaultPV.var) [lindex $valList 0]
    set BPLD(localMPSPV.var) [lindex $valList 1]
    set BPLD(linkFaultPV.var) [lindex $valList 2]
    set BPLD(main1fastPV.var) [lindex $valList 3]
    set BPLD(main2fastPV.var) [lindex $valList 4]
    set BPLD(ID1faultPV.var) [lindex $valList 5]
    set BPLD(ID2faultPV.var) [lindex $valList 6]
    
    switch $BPLD(IDchoice) {
	ID1 {
	    if !$BPLD(ID1faultPV.var) {
		append BPLD(faultDesc) "ID1 fault not detected"
		return failed
	    } 
	}
	ID2 {
	    if !$BPLD(ID2faultPV.var) {
		append BPLD(faultDesc) "ID2 fault not detected"
		return failed
	    }
	}
	Both {
	    if !$BPLD(ID1faultPV.var) {
		append BPLD(faultDesc) "ID1 fault not detected"
		return failed
	    }
	    if !$BPLD(ID2faultPV.var) {
		append BPLD(faultDesc) "ID2 fault not detected"
		return failed
	    }
	}
    }
    if {$BPLD(IDfaultPV.var)==0} {
	append BPLD(faultDesc) "ID fault not detected!"
	return failed
    }
    #local MPS, ID fault=2
    if {$BPLD(localMPSPV.var)!=2} {
	append BPLD(faultDesc) "Local MPS ID fault not detected!"
	return failed
    }
    #link fault
    if {$BPLD(linkFaultPV.var)!=2} {
	append BPLD(faultDesc) "Local MPS ID link fault not detected!"
	return failed
    }
    
    if {!$BPLD(main1fastPV.var)} {
	append BPLD(faultDesc) "Main1 fast fault failed"
	return failed
    }
    if {!$BPLD(main2fastPV.var)} {
	append BPLD(faultDesc) "Main2 fast fault failed"
	return failed
    }
    return passed
}


proc ResetIDBPMOffsets {args} {
    global BPLD 

    set BPLDNumber $BPLD(BPLDNumber)
    if [catch {APScavput -list=S$BPLD(BPLDNumber) -list=-LMPS:BPLD: -list=ID1,ID2 -list=:AIOR- -list=H,V -list=1,2 -list=-SP=0 -pend=30} result] {
	return -code error "Error reset ID bpm offsets: $result"
    }
    if [catch {APScavput -list=S$BPLD(BPLDNumber)-LMPS:P0_CntLimit-SP=100 -pend=30} result] {
	return -code error "Error reset ramp limit: $result"
    }
    set BPLD(userResetPV.var) 1
    pv putw BPLD(userResetPV.var) 30
}

proc ValidateIDBPMWithSyntheticData {args} {
    set coord x
    set reset 1
    APSParseArguments {coord reset}

    global BPLD outDir liberaList lab
    set window $BPLD(window)
    
    
    set sector $BPLD(sector)
    if {$sector==1} {
	set liberaList0 [regsub -all "n1" $liberaList 40]
    } else {
	set liberaList0 [regsub  -all "n1" $liberaList [format %02d [expr $sector-1]]]
    }
    set liberaList0 [regsub -all  "n2" $liberaList0 [format %02d [expr $sector+1]]]
   
    set liberaList0 [regsub -all "n" $liberaList0 [format %02d $sector]]
    set hostList ""
    set eventList ""
    if !$lab {
	foreach libera $liberaList0 {
	    lappend hostList $libera
	    lappend eventList 119
	}
    } else {
	set hostList {S44LBP1 S44LBP2 S44LBP3 S44LBP4 S45LBP5 S45LBP6 S45LBP7}
	set eventList {119 119 119 119 119 119 119}
    }
    
    switch $coord {
	x {
	    set plane H
	}
	y {
	    set plane V
	}
    }
    set Coord [string toupper $coord]
    if {$BPLD(window)=="Rect" || $BPLD(window)=="Diamond"} {
	set points 4
    } else {
	set points 12
    }
    
    set result0 passed
   
    set win $BPLD(window)
    for {set i 1} {$i<=$points} {incr i} {
	
	SetDPBPLDStatus "working with contour point - $i..."
	#generat gain, gain=0
	set BPLD(userResetPV.var) 1
	pv putw BPLD(userResetPV.var) 30
	after 3000
	foreach ID $BPLD(IDList) {
	    switch $ID {
		ID1 {
		    set sector1 $BPLD(sector1)
		    set sector2 $BPLD(sector2)
		}
		ID2 {
		    set sector1 $BPLD(sector2)
		    set sector2 [expr $BPLD(sector2)+1]
		}
	    }
	    SetDPBPLDStatus "ID: $ID"
	    if [catch {APScavput -list=S$BPLD(BPLDNumber)-LMPS:BPLD:${ID}_Enable-SP=1 -pend=30 } result] {
		return -code error "Error enable $ID: $result"
	    }
	    set s0 [set BPLD($ID.ID$win.S0.${i}$coord)]
	    set sp0 [set BPLD($ID.ID$win.S0.${i}${coord}')]
	    
	    #for any P0 and P1 combination, use L1 and L2 instead of L
	    set s1 [expr 1.0e3 * 1.10 * ($s0 - abs($BPLD($ID.L1)) * $sp0)]
	    set s2 [expr 1.0e3 * 1.10 * ($s0 + $BPLD($ID.L2)  * $sp0)]
	    #looks that the gain has limit of 2000, need increase the static and reduce the gain
	    set static 2000
	    set s1 [expr $s1/($static/1000.0)]
	    set s2 [expr $s2/($static/1000.0)]

	    puts "BPM for $ID: $BPLD($ID.liberaBPM1) $BPLD($ID.liberaBPM2)"
	    if [catch {GenerateGainWaveform -mainDir $outDir -filename $BPLD($ID.liberaBPM1)GainWF.sdds \
			   -bpmList $BPLD($ID.liberaBPM1) \
			   -gainType step -step0 1 \
			   -stepStart0 0 -stepEnd0 4095 -stepAmp0 $s1 } result] {
		return -code error "Error generate gain wf: $result"
	    }
	    if [catch {GenerateGainWaveform -mainDir $outDir -filename $BPLD($ID.liberaBPM2)GainWF.sdds \
			   -bpmList $BPLD($ID.liberaBPM2) \
			   -gainType step -step0 1 \
			   -stepStart0 0 -stepEnd0 4095 -stepAmp0 $s2 } result] {
		return -code error "Error generate gain wf: $result"
	    }
	    puts "$outDir/$BPLD($ID.liberaBPM1)GainWF.sdds"
	    puts "$outDir/$BPLD($ID.liberaBPM2)GainWF.sdds"
	    SetDPBPLDStatus "loading gain WF gain1=$s1 ($BPLD($ID.liberaBPM1)  gain2=$s2 ($BPLD($ID.liberaBPM2)..."
	    if [catch {exec sddswput $outDir/$BPLD($ID.liberaBPM1)GainWF.sdds } result] {
		return -code error "Error load gain WF: $result"
	    }
	    if [catch {exec sddswput $outDir/$BPLD($ID.liberaBPM2)GainWF.sdds } result] {
		return -code error "Error load gain WF: $result"
	    }
	    SetDPBPLDStatus "setup synthetic data..."
	    if [catch {SetupSyntheticData -lab $lab -hostList $hostList -eventList $eventList -plane $coord -statusCallback puts  \
			   -bpmList [list $BPLD($ID.bpm1) $BPLD($ID.bpm2)] -doubleSector [scan $BPLD(sector) %d] -repetition 100 \
			   -xstatic $static -ystatic $static } result] {
		return -code error "Error setup synthetic data: $result"
	    }
	}
	SetDPBPLDStatus "start event trigger...."
	#start trigger
	if $lab {
	    if [catch {exec caput DIA:EVG-SoftEvt:EvtCode-SP 119} result] {
		return -code error "Error set libera the trigger: $result"
	    }
	} else {
	    if [catch {exec caput S$BPLD(BPLDNumber)-MT:EVM1-SoftEvt:EvtCode-SP  119} result] {
		return -code error "Error set libera the trigger: $result"
	    }
	}
	after 5000
	
	set result [CheckIDFaultStatus]
	
	if {$result=="failed"} {
	    #test it again
	    SetDPBPLDStatus "setup synthetic data..."
	    foreach ID $BPLD(IDList) {
		if [catch {SetupSyntheticData -lab $lab -hostList $hostList -eventList $eventList -plane $coord -statusCallback puts  \
			       -bpmList [list $BPLD($ID.bpm1) $BPLD($ID.bpm2)] -doubleSector [scan $BPLD(sector) %d] -repetition 100 } result] {
		    return -code error "Error setup synthetic data: $result"
		}
	    }
	    SetDPBPLDStatus "start event trigger...."
	    #start trigger
	    if $lab {
		if [catch {exec caput DIA:EVG-SoftEvt:EvtCode-SP 119} result] {
		    return -code error "Error set libera the trigger: $result"
		}
	    } else {
		
	    }
	    after 5000
	    set result1 [CheckIDFaultStatus]
	    if {$result1=="failed"} {
		set result0 failed
		SetDPBPLDStatus "ID synthetic data validation at ${i}th point failed."
		break
	    } else {
		SetDPBPLDStatus "ID synthetic data validation at ${i}th point passed after seconded."	
	    }
	} else {
	    SetDPBPLDStatus "ID offset validation at ${i}th point passed."
	}
    }
    set BPLD($ID.$coord.result) $result0
}


proc SetIDBPMOffset {args} {
    global BPLD 
    
    set BPLDNumber $BPLD(BPLDNumber)
    
    switch $BPLD(window) {
	0 {
	    #diamond
	    set points 4
	    set win diamond
	} 
	1 {
	    #rect
	    set points 4
	    set win rect
	}
	2 {
	    #diamond-rect
	    set points 12
	    set win both
	}
    }
   
    set ID ID1
    set sector1 $BPLDNumber
    set sector2 [expr $BPLDNumber +1]
    set coord x
    for {set i 1} {$i<=$points} {incr i} {
	if !$BPLD(IDpoint.$i) {
	    continue
	}
	set s0 [set BPLD(ID$win.S0.${i}$coord)]
	set s0' [set BPLD(ID$win.S0.${i}${coord}')]
	set s1 [expr ($s0 - $BPLD(IDbpm.L)/2.0 * ${s0'})]
	set s2 [expr ($s0 + $BPLD(IDbpm.L)/2.0 * ${s0'})]
	#SetDPBPLDStatus "upstream bpm  offset: $s1  downstream bpm offset: $s2"
	#if [catch {exec cavput -list=S$BPLD(BPLDNumber)-LMPS:BPLD:${ID}:AIOR-${plane}1-SP=$s1,S$BPLD(BPLDNumber)-LMPS:BPLD:${ID}:AIOR-${plane}2-SP=$s2 -pend=10} result] {
	#    return -code error "Error setting ID bpm offset: $result"
	#}
	SetDPBPLDStatus "change B:P0 and A:P0 setpoints to steer the beam ($s1, $s2)..."
	if [catch {exec cavput -list=S${sector1}B:P0:ms:${coord}:SetpointAO=$s1,S${sector2}A:P0:ms:${coord}:SetpointAO=$s2 -pend=10 } result] {
	    return -code error "Error change setpoints: $result"
	}
    }
}

proc TransferOffset {args} {
    global BPLD
    
    set BPLDNumber $BPLD(BPLDNumber)
    set ID $BPLD(IDchoice)
    SetDPBPLDStatus "reading raw data..."
    set BPLD($ID.offsetH1) 0
    set BPLD($ID.offsetH2) 0
    set BPLD($ID.offsetV1) 0
    set BPLD($ID.offsetV2) 0
    set varList [list BPLD($ID.offsetH1) BPLD($ID.offsetH2) BPLD($ID.offsetV1) BPLD($ID.offsetV2)]
    pv putw $varList 30
    #if [catch {exec cavput -list=S$BPLD(BPLDNumber)-LMPS:BPLD:${ID}:AIOR- -list=H1,V1,H2,V2 -list=-SP=0 -pend=10} result] {
#	return -code error "Error set the offsets to 0: $result"
   # }
    after 2000
    if [catch {exec cavget -list=S$BPLD(BPLDNumber) -list=-LMPS:BPLD:${ID}_ -list=X1,X2,Y1,Y2 -list=-I -pend=10 -repeat=number=10,pause=1,average } valList] {
	return -code error "Error reading bpm positions: $valList"
    }
    set val1 [lindex $valList 0]
    set val2 [lindex $valList 1]
    set val3 [lindex $valList 2]
    set val4 [lindex $valList 3]
    
    set BPLD($ID.offsetH1) $val1
    set BPLD($ID.offsetH2) $val2
    set BPLD($ID.offsetV1) $val3
    set BPLD($ID.offsetV2) $val4
    
    set BPLD($ID.offsetH1.ref) $val1
    set BPLD($ID.offsetH2.ref) $val2
    set BPLD($ID.offsetV1.ref) $val3
    set BPLD($ID.offsetV2.ref) $val4
    
    pv putw $varList 30
    
    SetDPBPLDStatus " done."
    return
}

proc LogIDValidationResult {args} {
    global BPLD
    
    if ![file exist $BPLD(logFile)] {
	set BPLD(logID) [open $BPLD(logFile) a+]
	puts $BPLD(logID) "SDDS1"
	puts $BPLD(logID) "&column name=StartTime, type=string, &end"
	puts $BPLD(logID) "&column name=EndTime, type=string, &end"
	puts $BPLD(logID) "&column name=Sector, type=long, &end"
	puts $BPLD(logID) "&column name=IDType, type=string, &end"
	puts $BPLD(logID) "&column name=BPM, type=string &end"
	puts $BPLD(logID) "&column name=WindowShape, type=string, &end"
	puts $BPLD(logID) "&column name=Plane, type=string, &end"
	puts $BPLD(logID) "&column name=ValidateType, type=string, &end"
	puts $BPLD(logID) "&column name=ValidationResult, type=string, &end"
	puts $BPLD(logID) "&column name=FaultDescription, type=string,&end"
	puts $BPLD(logID) "&data mode=ascii, no_row_counts=1, &end"
	exec chmod 777 $BPLD(logFile)
    } else {
	set BPLD(logID) [open $BPLD(logFile) a+]
    }
    switch $BPLD(window) {
	Diamond {
	    set shape Diamond
	}
	Rect {
	    set shape Rectangle
	}
	Both {
	    set shape Diamond-Rect
	}
    }
    set ID $BPLD(IDchoice)
    set valList $BPLD(startTime)
    lappend valList $BPLD(endTime)
    lappend valList $BPLD(sector)
    lappend valList $BPLD(IDchoice)
    switch $BPLD(IDchoice) {
	Both {
	    lappend valList \"$BPLD(ID1.useBPMs) $BPLD(ID2.useBPMs)\"
	}
	default {
	    lappend valList \"$BPLD($BPLD(IDchoice).useBPMs)\"
	}
    }
    lappend valList $shape
    lappend valList $BPLD(plane)
    lappend valList $BPLD(testType)
    lappend valList $BPLD(result)
    lappend valList \"$BPLD(faultDesc)\"
    puts $BPLD(logID) "[join $valList]"
    flush $BPLD(logID)
   # close $BPLD(logID)
}

pv linkw $varList $pvList 50

SetupValidation

ValidateIDBPMs

puts $BPLD(logFile)
exit 0

