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

# version 1.0 1/18/2013 shang
# first version, for computing corrector noise time data from collected FPGA bpm data.

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)]
APSDebugPath
wm geometry . +10+10

set args $argv
set initialConfig ""
if {[APSStrictParseArguments { initialConfig  }] } {
    APSAlertBox [APSUniqueName .] \
      -errorMessage "Invalid arguments."
}

proc GenerateCorrConfig {args} {
    set plane h
    APSParseArguments {plane}
    global houtputDir voutputDir hnoiseModelConfigStatus vnoiseModelConfigStatus  hconfig vconfig 
    set outputDir [set ${plane}outputDir]
    set ${plane}config [APSNextGenerationedName -directory $outputDir -name ${plane}.[clock format [clock seconds] -format %Y-%m%d].00 -newFile 1 -separator .]

}
set stdLimit 0.01
set aveLimit 2
set bpmAverage 12
proc CreateCorrNoiseModelWidget {args} {
    set plane ""
    set parent ""
    APSParseArguments {plane parent}

    global hItemLabelList hItemList vItemLabelList vItemList hnoiseModelConfigStatus vnoiseModelConfigStatus
    global hlattice vlattice latticeDir simulationDir
    global bpmDataDir houtputDir voutputDir hmissingList vmissingList bpmDataDir largestSingularValues turns filterFreq cutoffFreq rfFreq
    global hrootname vrootname smoothPoints filterFreq stdLimit aveLimit hConfigDesc vConfigDesc hconfig vconfig hbpmDataDirList vbpmDataDirList
    
    set bpmDataDirList [set ${plane}bpmDataDirList]
    APSScrolledStatus .status -parent $parent -textVariable ${plane}noiseModelConfigStatus -width 100 -withButtons 1
    APSFrame .f -parent $parent
    set w $parent.f.frame
    $w configure -bd 0
    APSSRSectorButtons .bpmcorr -parent $w -rootname ${plane}noiseModel -description "noise model" \
      -label "" -sectorCount 40 -missingList [set ${plane}missingList] \
      -itemList [set ${plane}ItemList] -itemLabelList [set ${plane}ItemLabelList] \
      -orientation horizontal -sectorControl 1 -packOption "-side left" -separateCountButton 1
    set width 100
    APSFrameGrid .grid -parent $parent -xList {x1 x2}
    set w1 $parent.grid.x1
    set w2 $parent.grid.x2
    APSFileSelectWidget .lattice -parent $w1 -label "Lattice:" -pathVariableList latticeDir -mode directory -variable ${plane}lattice -width 40 \
      -incrementButtons 0 -contextHelp \
      "Enter the name of the lattice with which to compute the inverse response matrix."
    APSLabeledEntry .sing -parent $w2 -textVariable largestSingularValues -label "Number of singular values:" -width 40 
   # APSLabeledEntry .turns -parent $w1 -textVariable turns -label "Turns skipped:" -width 40 -contextHelp \
   #   "turns skipped in collecting FPGA bpm data."
   # APSLabeledEntry .rootname -parent $w2 -textVariable ${plane}rootname -label "Rootname:" -width 40 -contextHelp \
   #   "rootname for feedback simulation output files."
    APSLabeledEntry .limit -parent $w1 -textVariable stdLimit -width 40 -label "STD orbit absolute deviation limit:" -contextHelp \
        "Specifies the maximum absolute value that a std data point from a column may have before being considered an outlier. The bpms whose standard deviation is bigger than it will be removed."
    APSLabeledEntry .limit1 -parent $w2 -textVariable aveLimit -width 40 -label "Average Orbit standard deviation limit:" -contextHelp \
        "Specifies the maximum absolute value that a average data point from a column may have before being considered an outlier. The bpms whose standard deviation is bigger than it will be removed."
  #  APSLabeledEntry .ave -parent $w1 -textVariable turns -label "Number of turns (bpm average number):" -width 40
   # APSLabeledEntry .rf -parent $w1 -textVariable rfFreq -label "RF frequency(Hz):" -width 40
    global reprocess 
    set reprocess 0
    APSRadioButtonFrame .recompute -parent $w1 -label "Reprocess BPM data?" \
        -buttonList {Yes No} -valueList {1 0} -variable reprocess -orientation horizontal
    APSLabeledEntry .filter -parent $w2 -textVariable filterFreq -label "Filter frequency(Hz):" -width 40 \
      -contextHelp "filter frequency for simulation output files to save disk space, if 0 then keep all data."
    APSLabeledEntry .time -parent $w2 -textVariable timeOffset -label "Filter time offset (seconds):" -width 40 \
      -contextHelp "the start time offset for keeping the data."
    APSLabeledEntry .config -parent $w2 -textVariable ${plane}config -width 40 -label "noise model config:" 
   
    global P0Level P1Level RFLevel BMLevel IDLevel
    set P0Level 30
    set P1Level 50
    set RFLevel 10
    set IDLevel 0
    set BMLevel 0
    APSLabeledEntry .p0 -parent $w1 -textVariable P0Level -width 40 -label "Bergoz P0 noise level:"
    APSLabeledEntry .p1 -parent $w2 -textVariable P1Level -width 40 -label "Bergoz P1 noise level:"
    APSLabeledEntry .mn -parent $w1 -textVariable RFLevel -width 40 -label "Monopulse noise level:"
    APSLabeledEntry .bm -parent $w2 -textVariable BMLevel -width 40 -label "BM noise level:"
    APSLabeledEntry .id -parent $w1 -textVariable IDLevel -width 40 -label "ID xbpm noise level:"
    
    APSButton .gen -parent $w2.config -size small -text G -packOption "-side right" \
      -command  "GenerateCorrConfig -plane $plane"
    APSButton .pick -parent $w2.config -size small -text P -packOption "-side right" \
      -command "PickNoiseModel -plane $plane"
    APSButton .default -parent $w2.config -size small -text D -packOption "-side right" \
      -command "MakeDefaultConfig -plane $plane"
    APSButton .load -parent $w2.config -size small -text "Load" -packOption "-side right" \
        -command "LoadNoiseModelConfig -plane $plane"
    
    APSComboboxFrame .preset -parent $w2 -label "BPM noise data directory" \
      -packOption "-fill x" \
      -textVariable bpmDataDir \
      -itemList [join $bpmDataDirList] \
      -width 80 \
      -editable 1 \
      -callback "SelectDataDirectory -plane $plane -index" \
      -contextHelp "Select a bpm data directory."
    
    APSLabeledEntry .outdir -parent $w2 -textVariable ${plane}outputDir -label "Corr noise data dir:" -width 120
    APSLabeledEntry .desc -parent $w1 -textVariable ${plane}ConfigDesc -label "Description:" -width 80
   # APSButton .load -parent $parent -text "Load Config" -command "LoadConfig -plane $plane" -contextHelp "load the configuration from output dir (config.$plane) if it exists"
    APSFrame  .b1 -parent $parent
  #  APSFrame .b2 -parent $parent
    set w1 $parent.b1.frame
 #   set w2 $parent.b2.frame
    APSButton .process1 -parent $w1 -text "Process/Select BPM" -command "ProcessBPMData -plane $plane"
    APSButton .compute -parent $w1 -text "ComputeInverse" -command "ComputeInverse -plane $plane" \
        -contextHelp "compute the inverse response matrix."   
   
    APSButton .corr -parent $w1 -text "ComputeCorr" -command "ComputeCorrDataFromBpm -plane $plane"
    APSButton .plotcorr -parent $w1 -text "PlotCorrFreq" -command "PlotCorrectorPSD -plane $plane"
    APSButton .plotcorr1 -parent $w1 -text "PlotCorrTime" -command "PlotCorrectorTime -plane $plane"
    APSButton .compare -parent $w1 -text "CompareFPGAbpm Collected/Computed" -command "CompareBPM -plane $plane"
    APSButton .add -parent $w1 -text "Add BPM Noise" -command "AddBPMNoise -plane $plane"
    APSButton .plotnoise -parent $w1 -text "Plot BPM Noise" -command "PlotBPMNoiseData -plane $plane"
    APSSetSRSectorButtons -mode all-off -rootname  ${plane}noiseModel -sectorCount 40 -itemList [set ${plane}ItemList]
}

proc AddBPMNoise {args} {
    set plane ""
    APSParseArguments {plane}
    global bpmDataDir houtputDir voutputDir hnoiseModelCBWidget hnoiseModelConfigStatus
    global vnoiseModelConfigStatus  vnoiseModelCBWidget turns rfFreq hconfig vconfig
    global filterFreq P0Level P1Level RFLevel BMLevel IDLevel

    set outputDir [set ${plane}outputDir]
    switch $plane {
        h {
            set Plane X
        }
        v {
            set Plane Y
        }
    }
    set config [set ${plane}config]
    cd $outputDir/$config
    set files [glob -nocomplain *computed.sdds]
    if ![llength $files] {
        APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] bpm data not generated yet."
        return
    }
    set rows [exec sdds2stream -rows=bar [lindex $files 0]]
    set deltaT [expr 1.0/$rfFreq * 1296.0 * $turns]
    set bins 100
    set bpms [exec sdds2stream -col=BPMName rm1]
    foreach bpm $bpms {
        set file ${bpm}_computed.sdds
       
        set samplingRate [exec rpnl ${rfFreq} 1296.0 / ${turns} /]
        set endTime [exec rpnl $rows ${samplingRate} /]
        if [regexp {ID} $bpm] {
            set noiseLevel $IDLevel
        } elseif [regexp {BM} $bpm] {
            set noiseLevel $BMLevel
        } elseif  [regexp {P0} $bpm] {
            set noiseLevel $P0Level
        } elseif [regexp {P1} $bpm] {
            set noiseLevel $P1Level
        } else {
            set noiseLevel $RFLevel
        }
        set rmsTotal [exec rpnl ${noiseLevel} 1000.0 / sqr ${samplingRate} * 2.0 / sqrt]
        APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] computing noise for $bpm rms=$rmsTotal noiselevel=$noiseLevel..."
        
        if [catch {exec sddsconvert $file -pipe=out -del=par,Noise* \
                     | sddsprocess -pipe \
                     "-redefine=param,SamplingRate,${samplingRate},units=Hz" \
                     "-redefine=param,PSDLevel,${noiseLevel},units=nm\/\$sR\$eHz" \
                     "-redefine=param,rmsTotal,${noiseLevel} 1000000.0 / sqr ${samplingRate} * 2.0 / sqrt,units=mm" \
                     "-reprint=param,rmsTotalString,\$gs\$r\$bCalculated\$n = %0.3f %s,rmsTotal,rmsTotal.units" \
                     "-redefine=col,Noise,grnd rmsTotal *,units=mm" \
                     -process=Noise,rms,NoiseRMS \
                     "-redefine=param,NoiseRMS,NoiseRMS,symbol=\$gs\$r\$bNoise\$n,units=\$gm\$rm" \
                     "-reprint=param,NoiseRMSString,\$gs\$r\$bNoise\$n = %0.3f %s,NoiseRMS,NoiseRMS.units" \
                     | sddsprocess -pipe=in $bpm.noise "-redefine=col,ReconsWithNoise,Reconstructed Noise +"   } result] {
            return -code error $result
        }
        exec mv $bpm.noise $file
        catch {exec rm ${file}~ }
        if [catch {exec sddsprocess $file -pipe=out -filter=col,Time,0.05,15 \
                     | sddsfft -pipe=in $file.ifft -col=Time,Recon* -suppressAverage -psdoutput=integrated -truncate
            exec sddsprocess $file -pipe=out -filter=col,Time,0.05,15 \
                     | sddsfft -pipe=in $file.rfft -col=Time,Recon* -suppressAverage -psdoutput=rintegrated -truncate } result] {
            return -code error $result
        }
        catch {exec rm $file.rfft~ $file.ifft~}
        lappend rFFTList $file.rfft
        lappend iFFTList $file.ifft
        lappend fileList $file
    }

    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] done."
    return
    eval exec sddsplot -layout=1,2 -title=@bpmString -grap=line,vary -leg -col=Time,Recon* -split=page -sep=2 $fileList &
    
    eval exec sddsplot -layout=1,2 -title=@bpmString -grap=line,vary -leg=yname,edit=%/SqrtIntegPSD//  \
      -mode=x=log,x=spec -mode=y=log,y=spec \
      -col=f,Sqrt* -split=page -sep=2 $rFFTList \
      \"-topline=Reverse Integrated PSD\"  &
    eval exec sddsplot -layout=1,2 -title=@bpmString -grap=line,vary -leg=yname,edit=%/SqrtIntegPSD//  \
      -mode=x=log,x=spec -mode=y=log,y=spec \
      -col=f,Sqrt* -split=page -sep=2 $iFFTList \
      \"-topline=Forward Integrated PSD\"  &
}

set plotTime 0
set plotPSD 0
set plotRPSD 0
proc SelectPlotType {args} {
    global plotTime plotPSD plotRPSD
    APSDialogBox .plot -name "choose plots" -okCommand ""
    APSCheckButtonFrame .bpm -parent .plot.userFrame -orientation horizontal -buttonList "Time_Domain Integ_PSD Reverse_Integ_PSD"  \
        -variableList {plotTime plotPSD plotRPSD} -allNone 1
    tkwait window .plot
    return
}

set plotTimeCompare 0
set plotFFTCompare 0
set plotOrbitCompare 0
set plotPSDCompare 0

proc SelectCompareType {args} {
     global plotTimeCompare plotPSDCompare plotOrbitCompare plotFFTCompare
    APSDialogBox .compare -name "choose plots" -okCommand ""
    APSCheckButtonFrame .bpm -parent .compare.userFrame -orientation horizontal -buttonList "Time_Domain Integ_PSD FFT Orbit"  \
        -variableList {plotTimeCompare plotPSDCompare plotFFTCompare plotOrbitCompare} -allNone 1
    tkwait window .compare
    return

}
proc PlotBPMNoiseData {args} {
    set plane ""
    APSParseArguments {plane}
    global bpmDataDir houtputDir voutputDir hnoiseModelCBWidget hnoiseModelConfigStatus vnoiseModelConfigStatus  vnoiseModelCBWidget turns rfFreq hconfig vconfig
    global filterFreq P0Level P1Level RFLevel BMLevel IDLevel
   
    set outputDir [set ${plane}outputDir]
    switch $plane {
        h {
            set Plane X
        }
        v {
            set Plane Y
        }
    }
    set config [set ${plane}config]
    cd $outputDir/$config
    set files [glob -nocomplain *computed.sdds]
    if ![llength $files] {
        AddBPMNoise -plane $plane
    }
    set bpms [exec sdds2stream -col=BPMName rm1]
    foreach bpm $bpms {
        set file ${bpm}_computed.sdds
        if [file exist $file] {
            if {![file exist $file.rfft] || ![file exist $file.ifft]} {
                if [catch {exec sddsprocess $file -pipe=out -filter=col,Time,0.05,15 \
                             | sddsfft -pipe=in $file.ifft -col=Time,Recon* -suppressAverage -psdoutput=integrated -truncate
                    exec sddsprocess $file -pipe=out -filter=col,Time,0.05,15 \
                             | sddsfft -pipe=in $file.rfft -col=Time,Recon* -suppressAverage -psdoutput=rintegrated -truncate } result] {
                    return -code error $result
                }
                catch {exec rm $file.rfft~ $file.ifft~}
            }
            lappend rFFTList $file.rfft
            lappend iFFTList $file.ifft
            lappend fileList $file
        }
    }
    if ![llength $fileList] {
        APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] bpm noise data not processed yet."
        return
    }

    global plotTime plotPSD plotRPSD

    SelectPlotType
    
    if $plotTime {
        eval exec sddsplot -layout=1,2 -title=@bpmString -grap=line,vary -leg \
          -col=Time,ReconsWithNoise -col=Time,Reconstructed \
          -split=page -sep=2 $fileList &
    }
    if $plotRPSD {
        eval exec sddsplot -layout=1,2 -title=@bpmString -grap=line,vary -leg=yname,edit=%/SqrtIntegPSD//  \
          -mode=x=log,x=spec -mode=y=log,y=spec \
          -col=f,Sqrt* -split=page -sep=2 $rFFTList \
          \"-topline=Reverse Integrated PSD\"  &
    }
    if $plotPSD {
        eval exec sddsplot -layout=1,2 -title=@bpmString -grap=line,vary -leg=yname,edit=%/SqrtIntegPSD//  \
          -mode=x=log,x=spec -mode=y=log,y=spec \
          -col=f,Sqrt* -split=page -sep=2 $iFFTList \
          \"-topline=Forward Integrated PSD\"  &
    }
}

set smoothPoints 99
set filterFreq 2.5e3
set timeOffset 0
set cutoffFreq ""

set config matrix1
proc ComputeMatrixDialog {args} {
    global config
    APSDialogBox .diag  -name "choose config/irm type" -okCommand "return $config"
    APSRadioButtonFrame .choise -parent .diag.userFrame -label "Compute inverse for which config?"\
      -buttonList {"matrix1 of feedback simulation (all bpms and correctors)" "matrix2 (feedback correction) of feedback simulation (fast correctors and FPGA bpms)"} \
      -valueList {matrix1 matrix2} -variable config
    tkwait window .diag
    return $config
}

proc ComputeMatrix {args} {
    set plane ""
    APSParseArguments {plane}
    
    global simulationDir hFB vFB hItemList vItemList env hFBConfigStatus vFBConfigStatus
    global largestSingularValues refMatrixDir latticeDir hlattice vlattice hconfig vconfig

    
    set lattice [set ${plane}lattice]
    set config [set ${plane}config]
    ComputeMatrixDialog
    
    set refMatrixDir $latticeDir/$lattice/refMatrices
    set bpmList ""
    set corrList ""
    set bpmItemList {A:P0 A:P1 A:P2 A:P3 A:P4 B:P5 B:P4 B:P3 B:P2 B:P1 B:P0 C:P0 ID:P1 ID:P2}
    switch $plane {
        h {
            set corrItemList {A:H1 A:H2 A:H3 A:H4 B:H4 B:H3 B:H2 B:H1 C:H1}
            
        }
        v {
            set corrItemList {A:V1 A:V2 A:V3 A:V4 B:V4 B:V3 B:V2 B:V1 C:V1}
        }
    }
    set itemList [concat $bpmList $corrItemList]
    
    set rootname ${plane}FB
    for {set sector 1} {$sector<=40} {incr sector} {
        foreach pv $bpmItemList {
            set nameflag  ${rootname}S${sector}$pv
            global $nameflag
            if [set $nameflag] {
                lappend bpmList S${sector}$pv
            }
        }
        foreach pv $corrItemList {
            set nameflag  ${rootname}S${sector}$pv
            global $nameflag
            if [set $nameflag] {
                lappend corrList S${sector}$pv
            }
        }
    }
    if {![llength $bpmList]} {
        return -code error "No bpms selected."
    }
    if {![llength $corrList]} {
        return -code error "No correctors selected."
    }
    set matchOpt "-match=col,BPMName=[lindex $bpmList 0]"
    for {set i 1} {$i<[llength $bpmList]} {incr i} {
        append matchOpt ",BPMName=[lindex $bpmList $i],|"
    }
    APSSetVarAndUpdate ${plane}FBConfigStatus "[exec date] writing config file..."
    if [catch {exec sddsmakedataset $simulationDir/$config.bpm.$plane -par=NameType,type=string -data=MonitorNames \
                 -col=Name,type=string -data=[join $bpmList ,] 
        exec sddsmakedataset $simulationDir/$config.corr.$plane -par=NameType,type=string -data=CorrectorNames \
                 -col=Name,type=string -data=[join $corrList ,] 
        exec sddscombine $simulationDir/$config.bpm.$plane $simulationDir/$config.corr.$plane -over $simulationDir/$config.$plane } result] {
        return -code error "error in creating config: $result"
    }
    APSSetVarAndUpdate ${plane}FBConfigStatus "[exec date] computing inverse response matrix..."
    set refMatrix $refMatrixDir/${plane}.default
  
    if [catch {eval exec sddsconvert $refMatrix -pipe=out -retain=col,BPMName,[join $corrList ,] \
                 | sddsprocess -pipe $matchOpt \
                 | tee $simulationDir/${plane}_rm.$config \
                 | sddspseudoinverse -pipe=in -oldColumnNames=ControlName $simulationDir/${plane}_irm.$config  -largestSingularValues=$largestSingularValues \
                 -economy } result] {
        return -code error "Error in generating inverse response matrix: $result"
    }
    if [catch {exec sdds2headlessdata $simulationDir/${plane}_rm.$config $simulationDir/${plane}_rm.$config.dat -col=S* -order=column} result] {
        return -code error $result
    }
    if [catch {exec sdds2headlessdata $simulationDir/${plane}_irm.$config $simulationDir/${plane}_irm.$config.dat -col=S* -order=column} result] {
        return -code error $result
    }
    set cond [exec sdds2stream -par=ConditionNumber $simulationDir/${plane}_irm.$config]
    APSSetVarAndUpdate ${plane}FBConfigStatus "[exec date] condition number is $cond"
    APSSetVarAndUpdate ${plane}FBConfigStatus "[exec date] done."

}

if [catch {exec sddsprocess /home/helios/oagData/sr/BPMStatus/config.sdds -filter=col,NonexistentH,0,0 -pipe=out \
             -match=col,DeviceName=S1ID*,! \
             | sdds2stream -pipe -col=DeviceName } hAllBPMList] {
    puts stderr "$hAllBPMList"
}
if [catch {exec sddsprocess /home/helios/oagData/sr/BPMStatus/config.sdds -filter=col,NonexistentV,0,0 -pipe=out \
             -match=col,DeviceName=S1ID*,! \
             | sdds2stream -pipe -col=DeviceName } vAllBPMList] {
    puts stderr "$vAllBPMList"
}
proc ComputeInverse {args} {
    set plane ""
    APSParseArguments {plane}
    global houtputDir voutputDir hnoiseModel vnoiseModel hItemList vItemList env hnoiseModelConfigStatus vnoiseModelConfigStatus
    global largestSingularValues refMatrixDir latticeDir hlattice vlattice hConfigDesc vConfigDesc hconfig vconfig
    global hAllBPMList vAllBPMList

    set lattice [set ${plane}lattice]
    set outputDir [set ${plane}outputDir]
    set config corrModel
    set refMatrixDir $latticeDir/$lattice/refMatrices
    set bpmList ""
    set corrList ""
    set itemList [set ${plane}ItemList]
    set rootname ${plane}noiseModel
    for {set sector 1} {$sector<=40} {incr sector} {
        foreach pv $itemList {
            set nameflag  ${rootname}S${sector}$pv
            global $nameflag
            if [set $nameflag] {
                if {[regexp {H} $pv] || [regexp {V} $pv]} {
                    lappend corrList S${sector}$pv
                } else {
                    lappend bpmList S${sector}$pv
                }
            }
        }
    }
    if {![llength $bpmList]} {
        return -code error "No bpms selected."
    }
    if {![llength $corrList]} {
        return -code error "No correctors selected."
    }
    set matchOpt "-match=col,BPMName=[lindex $bpmList 0]"
    for {set i 1} {$i<[llength $bpmList]} {incr i} {
        append matchOpt ",BPMName=[lindex $bpmList $i],|"
    }
    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] writing config file..."
    set config  [set ${plane}config]
    if [file exist $outputDir/$config] {
        if ![APSYesNoPopUp "$config already exist, overwrite it?"] {
            return
        }
    } else {
        exec mkdir $outputDir/$config
    }
    if [catch {exec sddsmakedataset $outputDir/bpm.$plane -par=NameType,type=string -data=MonitorNames \
                 -col=Name,type=string -data=[join $bpmList ,] \
                 -par=Description,type=string "-data=[APSMakeSafeQualifierString [set ${plane}ConfigDesc]]"
        exec sddsmakedataset $outputDir/corr.$plane -par=NameType,type=string -data=CorrectorNames \
                 -col=Name,type=string -data=[join $corrList ,] \
                 -par=Description,type=string  "-data=[APSMakeSafeQualifierString [set ${plane}ConfigDesc]]"
        exec sddscombine $outputDir/bpm.$plane $outputDir/corr.$plane -over $outputDir/$config/config } result] {
        return -code error "error in creating config: $result"
    }
    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] computing inverse response matrix..."
    set refMatrix $refMatrixDir/${plane}.default
    if [catch {eval exec sddsconvert $refMatrix -pipe=out -retain=col,BPMName,[join $corrList ,] \
                 | sddsprocess -pipe $matchOpt \
                 | tee $outputDir/$config/rm \
                 | sddspseudoinverse -pipe=in -oldColumnNames=ControlName $outputDir/${config}/irm  -largestSingularValues=$largestSingularValues \
                 -economy } result] {
        return -code error "Error in generating inverse response matrix: $result"
    }
    set cond [exec sdds2stream -par=ConditionNumber $outputDir/$config/irm]
    if ![file exist $outputDir/${plane}.default] {
        cd $outputDir
        exec ln -s $config ${plane}.default
    }
    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] condition number is $cond"
    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] done."
    ComputeMatrix1 -plane $plane
}

proc ComputeMatrix1 {args} {
    set plane ""
    APSParseArguments {plane}
    global houtputDir voutputDir hnoiseModel vnoiseModel hItemList vItemList env hnoiseModelConfigStatus vnoiseModelConfigStatus
    global largestSingularValues refMatrixDir latticeDir hlattice vlattice hConfigDesc vConfigDesc hconfig vconfig
    global hAllBPMList vAllBPMList

    set outputDir [set ${plane}outputDir]
    set config [set ${plane}config]
    set lattice [set ${plane}lattice]
    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] compute the big matrix for feedback simulation..."
    set bpmList [set ${plane}AllBPMList]
    if [catch {exec sddsmakedataset $outputDir/bpm.$plane.all -par=NameType,type=string -data=MonitorNames \
                 -col=Name,type=string -data=[join $bpmList ,] \
                 -par=Description,type=string "-data=[APSMakeSafeQualifierString [set ${plane}ConfigDesc]]" 
        exec sddsprocess $outputDir/$config/config -match=par,NameType=CorrectorNames $outputDir/$config/corr 
        exec sddscombine $outputDir/bpm.$plane.all $outputDir/$config/corr -over $outputDir/$config/config1 } result] {
        return -code error "error in creating config1: $result"
    }
    set refMatrixDir $latticeDir/$lattice/refMatrices
    set refMatrix $refMatrixDir/${plane}.default
    
    set corrList [exec sdds2stream -col=Name $outputDir/$config/corr]
    # row filter for reference matrix.
    set monitorNameMatchOption ""
    set IDBPMList ""
    set BMBPMList ""
    foreach item $bpmList {
        switch -regexp $item {
            ID {
                lappend IDBPMList $item
            }
            BM {
                lappend BMBPMList $item
            }
        }
        if [string length $monitorNameMatchOption] {
            append monitorNameMatchOption ",BPMName=$item,|"
        } else {
            set monitorNameMatchOption "-match=column,BPMName=$item"
        }
    }
    set equationCmd ""
    if [llength $IDBPMList] {
        set IDBPMsKnownList [APSGetIDXRayBPMList -plane $plane]
        set IDBPMEqnList    [APSGetIDXRayEqnList -plane $plane]
        lappend equationCmd sddsprocess -pipe
        foreach item $IDBPMList {
            set index [lsearch -exact $IDBPMsKnownList $item]
            if $index==-1 {
                return -code error "ComputeMatrix1(error1): no information on $item"
            }
            set equation [lindex $IDBPMEqnList $index]
            if ![string length $equation] {
                return -code error "ComputeMatrix1(error2): no equation defined for $item."
            }
            lappend equationCmd "-define=column,$item,$equation"
        }
    }
    if [llength $BMBPMList] {
        set BMBPMsKnownList [APSGetBMXRayBPMList -plane $plane]
        set BMBPMEqnList    [APSGetBMXRayEqnList -plane $plane]
        if ![string length $equationCmd] {
            lappend equationCmd sddsprocess -pipe
        }
        foreach item $BMBPMList {
            set index [lsearch -exact $BMBPMsKnownList $item]
            if $index==-1 {
                return -code error "ComputeMatrix1(error3): no information on $item"
            }
            set equation [lindex $BMBPMEqnList $index]
            if ![string length $equation] {
                return -code error "ComputeMatrix1(error4): no equation defined for $item."
            }
            lappend equationCmd "-define=column,$item,$equation"
        }
    }
    if { [llength $IDBPMList] || [llength $BMBPMList] } {
        set tmpMatrix /tmp/[APSTmpString]
        if [catch {eval exec sddstranspose $refMatrix -pipe=out  \
                     | $equationCmd \
                     | sddstranspose -pipe=in $tmpMatrix \
                     -newColumnNames=OldColumnNames -oldColumnNames=BPMName} result] {
            return -code error "ComputeMatrix1(error5): $result"
        }
        set refMatrix $tmpMatrix
        APSAddToTmpFileList -ID srcorrnoisemodel -fileList $tmpMatrix
    }
    
    if [catch {eval exec sddsconvert $refMatrix -pipe=out -retain=col,BPMName,[join $corrList ,] \
                 | sddsprocess -pipe $monitorNameMatchOption \
                 | tee $outputDir/$config/rm1 \
                 | sddspseudoinverse -pipe=in -oldColumnNames=ControlName $outputDir/${config}/irm1  -largestSingularValues=$largestSingularValues \
                 -economy } result] {
        return -code error "Error in generating inverse response matrix1: $result"
    }
    if [catch {exec sdds2headlessdata $outputDir/$config/rm1 $outputDir/$config/rm1.dat -col=S* -order=column
        exec sdds2headlessdata $outputDir/$config/rm1 $outputDir/$config/irm1.dat -col=S* -order=column } result] {
        return -code error "Error in generating inverse response matrix1a: $result"
    }
    APSDeleteTmpFileList -ID srcorrnoisemodel
    set cond [exec sdds2stream -par=ConditionNumber $outputDir/$config/irm1]
    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] condition number is $cond"
    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] done."
}

proc PickNoiseModel {args} {
    set plane ""
    APSParseArguments {plane}
    global hconfig vconfig houtputDir voutputDir hConfigDesc vConfigDesc

    set outputDir [set ${plane}outputDir]
    if ![file exist $outputDir] {
        exec mkdir $outputDir
        APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] no configs found."
        return
    }
    cd $outputDir
    set fileList [glob -nocomplain ${plane}.*]
    if ![llength $fileList] {
        return -code error "No noise model created yet."
    }
    foreach file $fileList {
        set desc [lindex [exec sdds2stream -par=Description $file/config] 0]
        lappend choiceList "$file --> $desc"
    }
    set value [APSChooseItemFromList -name ChoiceList -height 30 \
                 -itemList $choiceList -returnList $fileList -multiItem 0]
    set ${plane}config $value
    if [file exist $outputDir/$value/config] {
        set ${plane}ConfigDesc [lindex [exec sdds2stream -par=Description $outputDir/$value/config] 0]
    }
}

proc MakeDefaultConfig {args} {
    set plane ""
    APSParseArguments {plane}
    global houtputDir voutputDir hconfig vconfig hnoiseModelConfigStatus vnoiseModelConfigStatus

    set outputDir [set ${plane}outputDir]
    cd $outputDir
    set config [set ${plane}config]
    if ![file exist $config] {
        APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] $config does not exist."
        return
    }
    catch {exec rm ${plane}.default}
    exec ln -s $config ${plane}.default
}

proc ProcessBPMData {args} {
    set plane ""
    APSParseArguments {plane}
    global turns
    global bpmDataDir houtputDir voutputDir hnoiseModelCBWidget hnoiseModelConfigStatus vnoiseModelConfigStatus  vnoiseModelCBWidget lattice deltaT revPeriod
    global outlierLimit hmissingList vmissingList stdLimit aveLimit rfFreq reprocess
    
    set outputDir [set ${plane}outputDir]
    
    switch $plane {
        h {
            set Plane X
        }
        v {
            set Plane Y
        }
    }
    set missingBPMs [set ${plane}missingList]
    if ![file exist $outputDir] {
        exec mkdir $outputDir
    }
    set deltaT [expr 1.0/$rfFreq * 1296.0 * $turns]
    set revPeriod [expr 1.0/$rfFreq * 1296.0]
    set oldDir [pwd]
    cd $bpmDataDir
    set fpgaSectorList [exec sdds2stream -col=Sector /home/helios/oagData/sr/FPGAbpm/sectors.sdds]
    set bpmList {A:P2 A:P3 A:P4 B:P5 B:P4 B:P3 B:P2}
   # set rfFreq 351934968.0
   # set turns 12
   # set deltaT [expr 1.0/$rfFreq * 1296.0 * $turns]
    
    set rootname ${plane}noiseModel
    set existList ""
    set fileList ""
    set bpmList1 ""
    set usedLattice ""
    set checked 0
    APSSetSRSectorButtons -mode all-off -rootname  ${plane}noiseModel -sectorCount 40 -itemList "A:P0 A:P1 A:P2 A:P3 A:P4 B:P5 B:P4 B:P3 B:P2 B:P1 B:P0 C:P0 ID:P1 ID:P2"
  
    if $reprocess {
        catch {exec rm  $outputDir/${Plane}_Orbit.sdds}
    }
    if ![file exist $outputDir/${Plane}_Orbit.sdds] {
        foreach sector $fpgaSectorList {
            foreach bpm $bpmList {
                if [regexp {A} $bpm ] {
                    set file [lindex [glob -nocomplain  S${sector}A-*.sdds] end]
                } else {
                    set file [lindex [glob -nocomplain  S${sector}B-*.sdds] end]
                }
                if ![string length $file] {
                    set file [lindex [glob -nocomplain  S${sector}${bpm}${Plane}*.sdds] end]
                }
                if [string length $file] {
                    
                    if !$checked {
                        set pars [exec sddsquery -par $file]
                        if [lsearch -exact $pars Lattice]>=0 {
                            set usedLattice [exec sdds2stream -par=Lattice $file]
                        }
                        if [lsearch -exact $pars RFFreq]>=0 {
                            set rfFreq [exec sdds2stream -par=RFFreq $file]
                        }
                        set checked 1
                    }
                    set cols [exec sddsquery -col $file]
                    set col S${sector}${bpm}:turnHistory:${Plane}position
                    if [lsearch -exact $cols $col]<0 {
                        continue
                    }
                    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] processing S${sector}${bpm}..."
                    set zeroFlag [exec sddsprocess -pipe=out $file \
                                    "-redefine=col,sqrPosition,S${sector}${bpm}:turnHistory:${Plane}position sqr" \
                                    -process=sqrPosition,sum,sumCheck \
                                    | sdds2stream -pipe=in -param=sumCheck]
                    set col S${sector}${bpm}:turnHistory:${Plane}position
                    if {$zeroFlag>1.0e-10} {
                        if [catch {exec  sddsprocess  -pipe=out $file \
                                     "-redefine=col,%s,%s $turns /,select=*position" \
                                     | sddsprocess -pipe \
                                     "-process=$col,average,${Plane}_AVE" \
                                     -process=$col,standarddeviation,${Plane}_STD \
                                     "-redefine=param,${Plane}_STD,${Plane}_STD,units=mm,symbol=\$gs\$r\$b${Plane}\$n" \
                                     "-redefine=param,${Plane}_AVE,${Plane}_AVE,units=mm,symbol=${Plane}_ave" \
                                     -print=param,bpmString,S${sector}${bpm} \
                                     | sddsconvert -pipe=in $outputDir/S${sector}${bpm}${Plane}.sdds -majorOrder=column \
                                     -retain=col,S${sector}${bpm}*position \
                                     -retain=param,bpmString,${Plane}_STD,${Plane}_AVE \
                                     -delete=param,* } result ] {
                            return -code error "$result"
                        }
                        lappend fileList $outputDir/S${sector}${bpm}${Plane}.sdds                  
                    }
                }
            }
        }
        
        if [string length $usedLattice] {
            set lattice $usedLattice
        }
        cd $outputDir
        
        if [catch {eval exec sddscombine $fileList -pipe=out -collapse -over | sddsprocess -pipe=in $outputDir/${Plane}_Orbit.sdds -redefine=col,Index,i_row} result] {
            return -code error $result
        }
       # if [catch {eval exec sddsxref $fileList -pipe=out -take=S* \
       #              | sddsconvert -pipe -retain=col,S* \
        #             | sddstranspose -pipe=in $outputDir/bpmData${Plane}All.sdds } result] {
         #   return -code error $result
        #}
    }
    cd $outputDir
    #exec sddsplot -title= -enumeratedscales=interval=10 \
    #  -col=bpmString,${Plane}_STD -graph=symbol,type=1,scale=2 ${Plane}_Orbit.sdds \
     # "-topline=${Plane} STD Orbit" &
    catch {exec sddsplot -layout=1,2 -enumeratedscales=interval=10  -title= \
      -col=bpmString,${Plane}_AVE,${Plane}_STD -graph=symbol,scale=2,conn ${Plane}_Orbit.sdds \
      -col=bpmString,${Plane}_AVE,${Plane}_STD -graph=errorBar,scale=2 ${Plane}_Orbit.sdds \
      "-topline=${Plane} Average Orbit with STD" -end \
      -col=bpmString,${Plane}_STD -graph=symbol,type=1,scale=2 ${Plane}_Orbit.sdds \
             "-topline=${Plane} STD Orbit" 2>/dev/null &}
    
    if [catch {exec sddsoutlier -pipe=out $outputDir/${Plane}_Orbit.sdds \
                 -absLimit=${stdLimit} -col=${Plane}_STD \
                 | sddsprocess -pipe=in ${Plane}_BPMs_std.sdds \
                 "-reedit=col,bpmString,%/_${Plane}//" \
                 -redefine=param,absLimit,${stdLimit},units=mm \
	         "-print=param,absLimitString,Abs. Dev. Limit = %0.3f mm,absLimit"} result] {
        return -code error "$result"
    }
     if [catch {exec sddsoutlier -pipe=out $outputDir/${Plane}_Orbit.sdds \
                 -stDevLimit=${aveLimit} -col=${Plane}_AVE \
                 | sddsprocess -pipe=in ${Plane}_BPMs_ave.sdds \
                 "-reedit=col,bpmString,%/_${Plane}//" \
                 -redefine=param,stDevLimit,${aveLimit},units=mm \
                  "-print=param,stDevLimitString,Std. Dev. Limit = %0.3f mm,stDevLimit"} result] {
        return -code error "$result"
    }
    if [catch {exec sddsselect ${Plane}_BPMs_std.sdds ${Plane}_BPMs_ave.sdds ${Plane}_BPMs.sdds -match=bpmString} result] {
        return -code error "$result"
    }
    set bpmList1 [exec sdds2stream -col=bpmString ${Plane}_BPMs.sdds]
    foreach bpm $bpmList1 {
        set nameFlag ${rootname}$bpm
        global $nameFlag
        if [set $nameFlag]!=1 {
            [set ${plane}noiseModelCBWidget($bpm)] invoke
        }
    }
    
   # if [catch {exec sddsselect ${Plane}_AvgOrbit.sdds  ${Plane}_BPMs.sdds -match=bpmString -invert  ${Plane}_BPMs.outlier -nowarnings} result] {
   #     return -code error "$result"
   # }
    catch {exec rm ${Plane}_BPMs_std.outlier}
    if [catch {exec sddsselect -pipe=out ${Plane}_Orbit.sdds ${Plane}_BPMs_std.sdds -match=bpmString -invert -nowarnings \
                 | sddsxref -pipe=in ${Plane}_BPMs_std.sdds ${Plane}_BPMs_std.outlier -transfer=param,absLimit,absLimitString -leave=*} result] {
        return -code error "$result"
    }
    catch {exec rm  ${Plane}_BPMs_ave.outlier}
    if [catch {exec sddsselect -pipe=out ${Plane}_Orbit.sdds ${Plane}_BPMs_ave.sdds -match=bpmString -invert -nowarnings \
                 | sddsxref -pipe=in ${Plane}_BPMs_ave.sdds ${Plane}_BPMs_ave.outlier -transfer=param,*Limit* -leave=*} result] {
        return -code error "$result"
    } 
    catch {exec sddsplot -layout=1,2 -col=Index,${Plane}_STD -graph=symbol,type=1,scale=2 ${Plane}_Orbit.sdds \
      -col=Index,${Plane}_STD -graph=symbol,type=1,scale=2 ${Plane}_BPMs_std.outlier -graph=symb,type=2,sub=2 -leg=spec=Outlier \
      -title=@absLimitString -end \
      -col=Index,${Plane}_AVE -graph=symbol,type=1,scale=2 ${Plane}_Orbit.sdds \
      -col=Index,${Plane}_AVE -graph=symbol,type=1,scale=2 ${Plane}_BPMs_ave.outlier -graph=symb,type=2,sub=2 -leg=spec=Outlier \
             -title=@stDevLimitString -end 2>/dev/null &}
    
    set rows [exec sdds2stream -rows=bare ${Plane}_BPMs_std.outlier]
    set rows1 [exec sdds2stream -rows=bare ${Plane}_BPMs_ave.outlier]
    if {$rows || $rows1} {
        
        APSDialogBox .bpm -name "Select outlier bpms" -okCommand "" -cancelButton 0
        if $rows {
            set bpmList0 [exec sdds2stream -col=bpmString ${Plane}_BPMs_std.outlier]
            set valList0 [exec sdds2stream -col=${Plane}_STD ${Plane}_BPMs_std.outlier]
            set bpmList ""
            set valList ""
            foreach bpm $bpmList0 val $valList0 {
                if [lsearch -exact $missingBPMs $bpm]<0 {
                    lappend bpmList $bpm
                lappend valList $val
                }
            }
            set rows [llength $bpmList]
            APSLabel .label -parent .bpm.userFrame -text "Select std  outlier bpms that you still want to use."
            APSLabel .label1 -parent .bpm.userFrame -text "BPM                Std(mm)"
            for {set i 0} {$i<$rows} {incr i} {
                lappend yList y$i
            }
            APSFrameGrid .grid -parent .bpm.userFrame -yList $yList -xList {x1 x2 x3}
            for {set i 0} {$i<$rows} {incr i} {
                set w1 .bpm.userFrame.grid.x1.y$i
                set w2 .bpm.userFrame.grid.x2.y$i
                set w3 .bpm.userFrame.grid.x3.y$i
                set bpm [lindex $bpmList $i]
                APSLabel .b -parent $w1 -text $bpm
                APSLabel .v -parent $w2 -text [format %.5f [lindex $valList $i]]
                global $rootname$bpm
                set $rootname$bpm 0
                set buttonName $w3.s
                checkbutton $w3.s -text "" -variable ${rootname}$bpm -anchor w  -command "SelectOutlierBPM -plane $plane -bpm $bpm -buttonName $buttonName"
                pack $w3.s -side top -fill x
            }
            APSLabel .l2 -parent .bpm.userFrame -text ""
            APSLabel .l3 -parent .bpm.userFrame -text ""
        }
        if $rows1 {
            set bpmList0 [exec sdds2stream -col=bpmString ${Plane}_BPMs_ave.outlier]
            set valList0 [exec sdds2stream -col=${Plane}_AVE ${Plane}_BPMs_ave.outlier]
            set bpmList ""
            set valList ""
            foreach bpm $bpmList0 val $valList0 {
                if [lsearch -exact $missingBPMs $bpm]<0 {
                    lappend bpmList $bpm
                    lappend valList $val
                }
            }
            set rows [llength $bpmList]
            APSLabel .label2 -parent .bpm.userFrame -text "Select ave  outlier bpms that you still want to use."
            APSLabel .label3 -parent .bpm.userFrame -text "BPM                Average(mm)"
            for {set i 0} {$i<$rows} {incr i} {
                lappend yList y1$i
            }
            APSFrameGrid .grid1 -parent .bpm.userFrame -yList $yList -xList {x1 x2 x3}
            for {set i 0} {$i<$rows} {incr i} {
                set w1 .bpm.userFrame.grid1.x1.y1$i
                set w2 .bpm.userFrame.grid1.x2.y1$i
                set w3 .bpm.userFrame.grid1.x3.y1$i
                set bpm [lindex $bpmList $i]
                APSLabel .b -parent $w1 -text $bpm
                APSLabel .v -parent $w2 -text [format %.5f [lindex $valList $i]]
                global $rootname$bpm
                set $rootname$bpm 0
                set buttonName $w3.s
                checkbutton $w3.s -text "" -variable ${rootname}$bpm -anchor w  -command "SelectOutlierBPM -plane $plane -bpm $bpm -buttonName $buttonName"
                pack $w3.s -side top -fill x
            }
        }
        tkwait window .bpm
    }
    
   
    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] done."
}

proc SelectOutlierBPM {args} {
    set plane ""
    set bpm ""
    set buttonName ""
    APSParseArguments {plane bpm buttonName}
    global hnoiseModelCBWidget hnoiseModelConfigStatus vnoiseModelConfigStatus  vnoiseModelCBWidget 
    set rootname ${plane}noiseModel
    set nameFlag ${rootname}$bpm
    global $nameFlag
    if [set $nameFlag]!=1 {
        $buttonName invoke
        [set ${plane}noiseModelCBWidget($bpm)] invoke
    }
    if [set $nameFlag] {
        [set ${plane}noiseModelCBWidget($bpm)] configure -selectcolor yellow
    }
}

set filterFreq 2.5e3
proc ComputeCorrDataFromBpm {args} {
    set plane ""
    APSParseArguments {plane}
    global bpmDataDir houtputDir voutputDir hnoiseModelCBWidget hnoiseModelConfigStatus vnoiseModelConfigStatus  vnoiseModelCBWidget turns rfFreq hconfig vconfig
    global filterFreq timeOffset
    
    set outputDir [set ${plane}outputDir]
    switch $plane {
        h {
            set Plane X
        }
        v {
            set Plane Y
        }
    }
    set config [set ${plane}config]
    if {![file exist $outputDir/$config/irm]} {
        APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] config does not exist, run computeInverse first."
        return
    }
    
    #changed to use irm get the corrects since the some of the correctors in config does not exist in irm due to they
    #are missing from the reference matrix (found mismatch correctors in config and irm matrix
    
    if [catch {exec sdds2stream $outputDir/$config/irm -col=ControlName } corrList] {
        APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] error reading $config: $corrList"
        return
    }
    
    if {[llength $corrList]==1} {
        set opt -rename=col,Column=$corrList
    } else {
        set opt -rename=col
        for {set i 0} {$i<[llength $corrList]} {incr i} {
            append opt ,Column[format %03d $i]=[lindex $corrList $i]
        }
    }
    cd $outputDir
   
    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] extracting bpm data..."
    #note here, the bpm order has to come from rm or irm, can not come from config
    #because the bpm order in config are different from the matrix file irm/rm
    if [catch {exec sdds2stream $outputDir/$config/rm -col=BPMName } bpmList] {
        APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] error reading $config: $bpmList"
        return
    }
    
    set fileList ""
    set option -match=col,OldColumnNames=[lindex $bpmList 0]*
    foreach bpm $bpmList {
        #lappend fileList $outputDir/${bpm}${Plane}.sdds
        # append option ,OldColumnNames=[lindex $bpmList $i]*,|
        lappend fileList $outputDir/${bpm}${Plane}.sdds
    }
    if [catch {eval exec sddsxref $fileList -pipe=out -take=S* -majorOrder=column -nowarnings\
                 | sddsconvert -pipe -retain=col,S* -majorOrder=column \
                 | sddstranspose -pipe=in  $outputDir/$config/bpmData.sdds -majorOrder=column } result] {
        return -code error "ComputeCorrDataFromBpm Error1: $result"
    }
    #  eval file delete -force $fileList
    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] extracting bpm data done"
    set timeFile [lindex [glob $bpmDataDir/S*.sdds] 0]
    catch {exec rm $outputDir/$config/corr.sdds.rfft}
    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] computing corrector data for $config..."
    if [catch {exec sddsmatrixop $outputDir/$config/irm -push=$outputDir/$config/bpmData.sdds -multiply -pipe=out -majorOrder=column \
                 | sddstranspose -pipe \
                 | sddsconvert -pipe=in $outputDir/$config/corr.sdds -del=col,OldColumnNames $opt} result] {
        return -code error "ComputeCorrDataFromBpm Error2: $result"
    }
    if [catch {exec sddstranspose $outputDir/$config/corr.sdds $outputDir/$config/corr.sdds.transpose } result] {
        return -code error "ComputeCorrDataFromBpm Error3: $result"
    }
    
    set deltaT [expr 1.0/$rfFreq * 1296.0 * $turns]
    if [catch {exec sddsxref $outputDir/$config/corr.sdds $timeFile -take=Time -pipe=out \
                 | sddsprocess -pipe=in $outputDir/$config/corr.sdds.1 "-redefine=col,%s,%s,units=A,select=S*"  -nowarnings } result] {
        return -code error "ComputeCorrDataFromBpm Error4: $result"
    }
    exec mv $outputDir/$config/corr.sdds.1 $outputDir/$config/corr.sdds
    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] done."
    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] computing bpm initial error with corrector noise..."
    if ![file exist $outputDir/$config/irm1] {
        if [catch {ComputeMatrix1 -plane $plane} result] {
            return -code error "ComputeCorrDataFromBpm Error5: $result"
        }
    }
    
    set deltaT [expr 1.0/$rfFreq * 1296.0 * $turns]
    set rows 261644 
    set length [expr ($rows-1)*$deltaT]
    set df [expr 1.0/$length]
    if $filterFreq {
        set rows [expr int($filterFreq/$df)]
    }
    set endT [expr $timeOffset + $deltaT * $rows]
    puts "$timeOffset $endT $timeFile"
    if [catch {exec sddsmatrixop $outputDir/$config/rm1 -push=$outputDir/$config/corr.sdds.transpose -mult -majorOrder=column \
                 -pipe=out \
                 | sddsxref -pipe $outputDir/$config/rm1 -take=BPMName \
                 | sddstranspose -pipe -noOldColumnNames -newColumnNames=BPMName \
                 | sddsxref -pipe $timeFile -take=Time -nowarnings \
                 | tee /tmp/aa \
                 | sddsprocess -pipe=in -filter=col,Time,$timeOffset,$endT \
                 $outputDir/$config/bpm0.sdds  } result] {
        return -code error ComputeCorrDataFromBpm "Error in computing bpm initial data: $result"
    }
   
   # if [catch {exec sdds2headlessdata $outputDir/$config/bpm0.sdds \
   #              $outputDir/$config/bpm0.sdds.dat -col=S* -order=column} result] {
    #    return -code error $result
    #}
    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] bpm data was computed."
    set bpmList [exec sdds2stream -col=BPMName $outputDir/$config/rm1]
   
    foreach bpm $bpmList {
        APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] create computed data for $bpm."  
        if [catch {exec sddsconvert $outputDir/$config/bpm0.sdds -retain=col,Time,$bpm -pipe=out -majorOrder=column  \
                     -rename=col,$bpm=Reconstructed \
                     | sddsprocess -pipe=in -reprint=par,bpmString,$bpm $outputDir/$config/${bpm}_computed.sdds -majorOrder=column } result] {
            return -code error "ComputeCorrDataFromBpm Error: $bpm: $result"
        }
    }
    catch {exec rm $outputDir/$config/bpmData.sdds $outputDir/$config/corr.sdds.transpose $outputDir/$config/corr.sdds~ $outputDir/$config/bpm0.sdds~}
    
    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] done."
    return
}

proc CompareBPM {args} {
    set plane ""
    APSParseArguments {plane}
    global bpmDataDir houtputDir voutputDir hnoiseModelCBWidget hnoiseModelConfigStatus vnoiseModelConfigStatus  vnoiseModelCBWidget turns rfFreq hconfig vconfig
    global filterFreq

    set outputDir [set ${plane}outputDir]
    set config [set ${plane}config]
    
    cd $outputDir/$config
    
    switch $plane {
        h  {
            set Plane X
        } 
        v {
            set Plane Y
        }
    }
    set plotOption "-grap=line,vary -sep=2 -leg -yscalesgroup=namestring"
    set bpms [exec sdds2stream -col=BPMName $outputDir/$config/rm]
    set fileList ""
    set fileList1 ""
    set deltaT [expr 1.0/$rfFreq * 1296.0 * $turns]
    set timeFile  [lindex [glob $bpmDataDir/S*.sdds] 0]
    foreach bpm $bpms {
        if ![file exist ../${bpm}${Plane}.sdds] {
            APSSetVarAndUpdate ${plane}noiseModelConfigStatus "Error: $bpm data not found."
            continue
        }
        if ![file exist ${bpm}_computed.sdds] {
           APSSetVarAndUpdate ${plane}noiseModelConfigStatus "Error: $bpm computed data not computed (it might does not exist in rm1)."
           continue
        }
        set mtime [file mtime ${bpm}_computed.sdds]
        if [file exist ${bpm}_compare.sdds] {
            set mtime1 [file mtime ${bpm}_compare.sdds]
        } else {
            set mtime1 0
        }
        if {$mtime1<$mtime} {
            APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date]: extracting $bpm data ..."
            if [catch {exec sddsxref ../${bpm}${Plane}.sdds $timeFile ${bpm}_0a.sdds -take=Time
                exec  sddsxref ${bpm}_computed.sdds ${bpm}_0a.sdds -pipe=out -equate=Time \
                         -rename=col,${bpm}:turnHistory:${Plane}position=Data  \
                         | sddsprocess -pipe -process=Reconstructed,ave,Reconstructed_AVE \
                         -process=Reconstructed,standarddeviation,Reconstructed_STD \
                         -process=Data,ave,Data_AVE \
                         -process=Data,standarddeviation,Data_STD \
                         -reprint=par,bpmString,$bpm \
                         | sddsprocess -pipe=in ${bpm}_compare.sdds -majorOrder=column \
                         "-redefine=col,Reconstructed,Reconstructed Reconstructed_AVE -,units=mm" \
                         "-redefine=col,Data,Data Data_AVE -,units=mm" } result] {
                return -code error $result
            }
            if [catch {exec sddsfft ${bpm}_compare.sdds ${bpm}_compare.sdds.fft -col=Time,Reconstructed,Data -majorOrder=column  \
                         -truncate -psdOutput=plain,integrated -suppressAve} result] {
                return -code error $result
            }
            catch {exec rm ${bpm}_0a.sdds}
        }
        lappend fileList ${bpm}_compare.sdds
        if ![file exist ${bpm}_compare.sdds.fft] {
            if [catch {exec sddsfft ${bpm}_compare.sdds ${bpm}_compare.sdds.fft -col=Time,Reconstructed,Data -majorOrder=column  \
                         -truncate -psdOutput=plain,integrated -suppressAve} result] {
                return -code error $result
            }
        }
        lappend fftList ${bpm}_compare.sdds.fft
    }
    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "done."
    if ![file exist orbit.sdds] {
        if [catch {eval exec sddscombine $fileList -pipe=out -collapse -over -majorOrder=column  \
                     | sddsprocess -pipe=in orbit.sdds -redefine=col,Index,i_row,type=long } result] {
            return -code error $result
        }
    }
    global plotTimeCompare plotFFTCompare plotOrbitCompare plotPSDCompare

    SelectCompareType
    if $plotOrbitCompare {
        exec sddsplot -enumeratedscales=interval=10  -title= \
          -grap=sym,scale=2,vary=sub,conn=sub -sep=2 \
          -col=bpmString,Reconstructed_AVE orbit.sdds -leg=spec=X_ave_recon \
          -col=bpmString,Data_AVE orbit.sdds -leg=spec=X_ave_data  &
    }
    if $plotTimeCompare {
        catch {eval exec sddsplot \"-topline=Average Orbit Filtered FPGA BPM data and computed from noise model\" \
                 -title=@bpmString -split=page \
                 -grap=line,vary -sep=2 -leg -col=Time,Reconstructed -col=Time,Data $fileList 2>/dev/null &} result
    }
    if $plotPSDCompare {
        eval exec sddsplot -title=@bpmString \"-topline=Frequency Domain Integrated PSD of  FPGA BPM Data and Computed From Noise Model\" -layout=1,2 \
          -grap=line,vary -sep=2 -groupby=request -split=page -ylabel=IntegratedPSD \
          -legend=yname,edit=%/SqrtIntegPSD// -col=f,SqrtInteg* $fftList  &
    }
    
    if $plotFFTCompare {
        eval exec sddsplot -title=@bpmString \"-topline=Frequency Domain FFT of FPGA BPM Data and Computed From Noise Model\" -layout=1,2 \
          -grap=line,vary -sep=2  -split=page -ylabel=FFT \
          -legend=yname,edit=%/FFT// -col=f,FFT* $fftList & 
    }
}

proc PlotCorrectorTime {args} {
    set plane ""
    APSParseArguments {plane}
    global houtputDir voutputDir deltaT turns rfFreq corrType hnoiseModelConfigStatus vnoiseModelConfigStatus hconfig vconfig

    set outputDir [set ${plane}outputDir]
    set deltaT [expr 1.0/$rfFreq * 1296.0 * $turns]
    set config [set ${plane}config]
    if ![file exist $outputDir/$config/corr.sdds] {
        APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] computing corrector data..."
        ComputeCorrDataFromBpm -plane $plane
    }
    
    switch $plane {
        h {
            set corrList {A:H1 A:H2 A:H3 A:H4 B:H4 B:H3 B:H2 B:H1 C:H1}
        }
        v {
            set corrList {A:V1 A:V2 A:V3 A:V4 B:V4 B:V3 B:V2 B:V1 C:V1}
        }
    }
    foreach corr $corrList {
        global $corr
        set $corr 0
    }
    APSDialogBox .corr -name "choose plots" -okCommand "PlotCorrTime -plane $plane"
    APSCheckButtonFrame .bpm -parent .corr.userFrame -orientation horizontal -buttonList $corrList -variableList $corrList \
      -limitPerRow 7 -label "Select bpm type for plot FFT ratio:" -allNone 1
    tkwait window .corr
}

proc PlotCorrTime {args} {
    set plane ""
    APSParseArguments {plane}
    global houtputDir voutputDir hconfig vconfig

    set outputDir [set ${plane}outputDir]
    switch $plane {
        h {
            set corrList {A:H1 A:H2 A:H3 A:H4 B:H4 B:H3 B:H2 B:H1 C:H1}
        }
        v {
            set corrList {A:V1 A:V2 A:V3 A:V4 B:V4 B:V3 B:V2 B:V1 C:V1}
        }
    }
    set config [set ${plane}config]
    eval global $corrList
    set cols [exec sddsquery -col $outputDir/$config/corr.sdds]
    foreach corr $corrList {
        if [set $corr] {
            if [regexp $corr $cols] {
                catch { exec sddsplot $outputDir/$config/corr.sdds -sep -same=y  \
                          -graphic=line,vary -order=spectral -legend \
                          -col=Time,*${corr} 2>/dev/null & }
            }
        }
    }
}


 set Forward_Integrated_PSD 1
set Reverse_Integrated_PSD 0
set Plain_PSD 0
set FFT 0
proc PlotCorrectorPSD {args} {
    set plane ""
    APSParseArguments {plane}
    global houtputDir voutputDir deltaT turns rfFreq corrType hnoiseModelConfigStatus vnoiseModelConfigStatus hconfig vconfig

    set outputDir [set ${plane}outputDir]
    
    set config [set ${plane}config]
    set deltaT [expr 1.0/$rfFreq * 1296.0 * $turns]
    if ![file exist $outputDir/$config/corr.sdds] {
        APSSetVarAndUpdate ${plane}NoiseModelConfigStatus "[exec date] computing corrector data..."
        ComputeCorrDataFromBpm -plane $plane
        
        
    }
    if ![file exist $outputDir/$config/corr.sdds.rfft] {
        
        APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] processing corrector rintegrated fft..."
        if [catch {exec sddsfft $outputDir/$config/corr.sdds  $outputDir/$config/corr.sdds.rfft -majorOrder=column  \
                     -col=Time,S* -psdoutput=plain,rintegrated -suppressaverage } result] {
            return -code error "Error doing fft for correctors: $result"
        }
    }
    if ![file exist $outputDir/$config/corr.sdds.ifft] {
        APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] processing corrector integrated fft..."
        if [catch {exec sddsfft $outputDir/$config/corr.sdds $outputDir/$config/corr.sdds.ifft -majorOrder=column  \
                     -col=Time,S* -psdoutput=plain,integrated -suppressaverage } result] {
            return -code error "Error doing fft for correctors: $result"
        }
    }
    switch $plane {
        h {
            set corrList {A:H1 A:H2 A:H3 A:H4 B:H4 B:H3 B:H2 B:H1 C:H1}
        }
        v {
            set corrList {A:V1 A:V2 A:V3 A:V4 B:V4 B:V3 B:V2 B:V1 C:V1}
        }
    }
    foreach corr $corrList {
        global $corr
        set $corr 0
    }
    global Forward_Integrated_PSD Reverse_Integrated_PSD Plain_PSD FFT
   
    APSDialogBox .corr -name "choose plots" -okCommand "PlotCorrPSD -plane $plane"
    APSCheckButtonFrame .bpm -parent .corr.userFrame -orientation horizontal -buttonList $corrList -variableList $corrList \
        -limitPerRow 7 -label "Select bpm type for plot FFT ratio:" -allNone 1
    APSCheckButtonFrame .fft -parent .corr.userFrame -orientation horizontaol -buttonList "Forward_Integrated_PSD Reverse_Integrated_PSD Plain_PSD FFT" \
      -variableList "Forward_Integrated_PSD Reverse_Integrated_PSD Plain_PSD FFT" -allNone 1
    tkwait window .corr
}

proc PlotCorrPSD {args} {
    set plane ""
    APSParseArguments {plane}
    global houtputDir voutputDir hconfig vconfig Forward_Integrated_PSD Reverse_Integrated_PSD Plain_PSD FFT

    set outputDir [set ${plane}outputDir]
    set config [set ${plane}config]
    switch $plane {
        h {
            set corrList {A:H1 A:H2 A:H3 A:H4 B:H4 B:H3 B:H2 B:H1 C:H1}
        }
        v {
            set corrList {A:V1 A:V2 A:V3 A:V4 B:V4 B:V3 B:V2 B:V1 C:V1}
        }
    }
    eval global $corrList
    set cols [exec sddsquery -col $outputDir/$config/corr.sdds.rfft]
    foreach corr $corrList {
        if [set $corr] {
            if [regexp $corr $cols] {
                if $Forward_Integrated_PSD {
                    catch { exec sddsplot $outputDir/$config/corr.sdds.ifft  \
                              "-title=Forward Integrated PSD" \
                              -graphic=line,vary -order=spectral -legend \
                              -mode=x=log,x=spec -mode=y=log,y=spec \
                              -col=f,SqrtIntegPSD*$corr  2>/dev/null & } result
                }
                if $Reverse_Integrated_PSD {
                    catch { exec sddsplot $outputDir/$config/corr.sdds.rfft  \
                              "-title=Reverse Integrated PSD" \
                              -graphic=line,vary -order=spectral -legend \
                              -mode=x=log,x=spec -mode=y=log,y=spec \
                              -col=f,SqrtIntegPSD*$corr  2>/dev/null & } result
                }
                if $FFT {
                    catch { exec sddsplot $outputDir/$config/corr.sdds.rfft  \
                              -sep=namestring \
                              "-title=FFT" \
                              -graphic=line,vary -order=spectral -legend \
                              -mode=x=log,x=spec -mode=y=log,y=spec \
                              -col=f,FFT*$corr  2>/dev/null & } result
                }
                if $Plain_PSD {
                     catch { exec sddsplot $outputDir/$config/corr.sdds.rfft  \
                               -sep=namestring \
                              "-title=Plain PSD" \
                              -graphic=line,vary -order=spectral -legend \
                              -mode=x=log,x=spec -mode=y=log,y=spec \
                              -col=f,PSD*$corr  2>/dev/null & } result
                }
            }
        }
    }
}

proc LoadNoiseModelConfig {args} {
    set plane ""
    APSParseArguments {plane}
    global houtputDir voutputDir hnoiseModelConfigStatus vnoiseModelConfigStatus hnoiseModelCBWidget  vnoiseModelCBWidget hconfig vconfig
    
    set outputDir [set ${plane}outputDir]
    switch $plane {
        h {
            set corrItemList {A:H1 A:H2 A:H3 A:H4 B:H4 B:H3 B:H2 B:H1 C:H1}
            set bpmItemList {A:P0 A:P1 A:P2 A:P3 A:P4 B:P5 B:P4 B:P3 B:P2 B:P1 B:P0 C:P0 ID:P1 ID:P2}
        }
        v {
            set corrItemList {A:V1 A:V2 A:V3 A:V4 B:V4 B:V3 B:V2 B:V1 C:V1}
            set bpmItemList {A:P0 A:P1 A:P2 A:P3 A:P4 B:P5 B:P4 B:P3 B:P2 B:P1 B:P0 C:P0 ID:P1 ID:P2 BM:P1 BM:P2}
        }
    }
    set config [set ${plane}config]
    if ![file exist $outputDir/$config/config] {
        APSSetVarAndUpdate ${plane}noiseNodelStatus "[exec date] $config does not exist"
        return
    }
    
    if [catch {exec sddsprocess $outputDir/$config/config -match=par,NameType=MonitorNames -pipe=out \
                 | sdds2stream -pipe=in -col=Name } bpmList] {
        APSSetVarAndUpdate ${plane}noiseModelStatus "[exec date] error in reading $config: $bpmList"
        return
    }
    if [catch {exec sddsprocess $outputDir/$config/config -match=par,NameType=CorrectorNames -pipe=out \
                 | sdds2stream -pipe=in -col=Name } corrList] {
        APSSetVarAndUpdate ${plane}noiseModelStatus "[exec date] error in reading $config: $corrList"
        return
    }
    
    APSSetSRSectorButtons -mode all-off -rootname  ${plane}noiseModel -sectorCount 40 -itemList $bpmItemList
    APSSetSRSectorButtons -mode all-off -rootname  ${plane}noiseModel -sectorCount 40 -itemList $corrItemList
    set rootname ${plane}noiseModel
    foreach bpm $bpmList {
        set nameFlag ${rootname}$bpm
        global $nameFlag
        [set ${plane}noiseModelCBWidget($bpm)] invoke
        # if [set $nameFlag]!=1 {
        #    [set ${plane}FBCBWidget($bpm)] invoke
        #}
    }
    foreach corr $corrList {
        set nameFlag ${rootname}$corr
        global $nameFlag
        [set ${plane}noiseModelCBWidget($corr)] invoke
        #if [set $nameFlag]!=1 {
        #    [set ${plane}FBCBWidget($corr)] invoke
        #} else {
        #    [set ${plane}FBCBWidget($corr)] invoke
        #}
    }
    set cond [exec sdds2stream -par=ConditionNumber $outputDir/$config/irm]
    APSSetVarAndUpdate ${plane}noiseModelConfigStatus "[exec date] $config loaded, condition number is $cond"
}

proc SelectDataDirectory {args} {
    global hbpmDataDir houtputDir hturns  hlattice hbpmDataDirList hbpmTurnsList hbpmLatticeList hrfFreq latticeDir vnoiseModel 
    global vbpmDataDir voutputDir vturns  vlattice vbpmDataDirList vbpmTurnsList vbpmLatticeList vrfFreq  vnoiseModel
    global  hnoiseModelCBWidget  vnoiseModelCBWidget
    
    set index ""
    set plane ""
    APSParseArguments {index plane}

    if {$index == ""} {
        return -code error " No index value passed."
    }
    set bpmDataDirList [set ${plane}bpmDataDirList]
    set bpmTurnsList [set ${plane}bpmTurnsList]
    set bpmLatticeList [set ${plane}bpmLatticeList]
    
    set ${plane}bpmDataDir [lindex $bpmDataDirList $index]
    set bpmDataDir [set ${plane}bpmDataDir]
    set ${plane}outputDir $bpmDataDir/CorrData
    set ${plane}turns [lindex $bpmTurnsList $index]
    set ${plane}lattice [lindex $bpmLatticeList $index]

    set lattice [set ${plane}lattice]
    
    set file [lindex [glob -nocomplain $bpmDataDir/S*P*.sdds] end]
    if [string length $file] {
        set pars [exec sddsquery -par $file]
        if [lsearch -exact $pars RFFreq]>=0 {
            set ${plane}rfFreq [exec sdds2stream -par=RFFreq $file]
        }
    }
    foreach plane {h v} {
        set refMatrix $latticeDir/$lattice/refMatrices/${plane}.default
        set bpmList [exec sdds2stream -col=BPMName $refMatrix]
        set corrList [exec sddsquery -col $refMatrix | grep S]
        set rootname ${plane}noiseModel
        switch $plane {
            h {
                set corrItemList {A:H1 A:H2 A:H3 A:H4 B:H4 B:H3 B:H2 B:H1 C:H1}
                set bpmItemList {A:P0 A:P1 A:P2 A:P3 A:P4 B:P5 B:P4 B:P3 B:P2 B:P1 B:P0 C:P0 ID:P1 ID:P2}
            }
            v {
                set corrItemList {A:V1 A:V2 A:V3 A:V4 B:V4 B:V3 B:V2 B:V1 C:V1}
                set bpmItemList {A:P0 A:P1 A:P2 A:P3 A:P4 B:P5 B:P4 B:P3 B:P2 B:P1 B:P0 C:P0 ID:P1 ID:P2 BM:P1 BM:P2}
            }
        }
        for {set sector 1} {$sector<41} {incr sector} {
            foreach item $bpmItemList {
                set bpm S${sector}$item
                set nameFlag ${rootname}$bpm
                global $nameFlag
                if [lsearch -exact $bpmList $bpm]<0 {
                    set $nameFlag 0
                    [set ${plane}noiseModelCBWidget($bpm)] configure  -state disabled
                } else {
                    [set ${plane}noiseModelCBWidget($bpm)] configure -state normal
                }
            }
            foreach item $corrItemList {
                set corr S${sector}$item
                set nameFlag ${rootname}$bpm
                global $nameFlag
                if [lsearch -exact $corrList $corr]<0 {
                    set $nameFlag 0
                    [set ${plane}noiseModelCBWidget($corr)] configure  -state disabled
                } else {
                    [set ${plane}noiseModelCBWidget($corr)] configure -state normal
                }
            }
        }
    }
    update
}

set fpgaSectorList [exec sdds2stream -col=Sector /home/helios/oagData/sr/FPGAbpm/sectors.sdds]
set bpmList {A:P2 A:P3 A:P4 B:P5 B:P4 B:P3 B:P2}
set rfFreq 351934968.0
set turns 12
set deltaT [expr 1.0/$rfFreq * 1296.0 * $turns]

set latticeDir  /home/helios/oagData/sr/orbitControllaw/lattices
set hlattice sigmax120um-S32
set vlattice  sigmax120um-S32
set refMatrixDir /home/helios/oagData/sr/orbitControllaw/lattices/default/refMatrices
set largestSingularValues 320

set hItemLabelList {AP0 AH1 AP1 AH2 AP2 AH3 AP3 AP4 AH4 BP5 BH4 BP4 BP3 BH3 BP2 BH2 BP1 BH1 BP0 CH1 CP0 ID1 ID2}
set hItemList {A:P0 A:H1 A:P1 A:H2 A:P2 A:H3 A:P3 A:P4 A:H4 B:P5 B:H4 B:P4 B:P3 B:H3 B:P2 B:H2 B:P1 B:H1 B:P0 C:H1 C:P0 ID:P1 ID:P2}
set vItemLabelList [concat [regsub -all {H} $hItemLabelList "V"] BM1 BM2]
set vItemList [concat [regsub -all {H} $hItemList "V"] BM:P1 BM:P2]
set hnoiseModelConfigStatus ""
set vnoiseModelConfigStatus ""
set tabs {"Horizontal" "Vertical"}
#set bpmDataDir /home/helios/SR/daily/2012/10/30/2/fpga_12sec
#set outputDir  /home/helios/SR/daily/2012/10/30/2/fpga_12sec/CorrData
set simulationDir [APSGoToDailyDirectory -subdirectory feedbackSim]
#set outputDir /home/oxygen/SHANG/daily/1211/19/2/CorrData
#set simulationDir /home/oxygen/SHANG/daily/1211/19/2/feedbackSim
set hrootname h
set vrootname v

set hmissingBpms [exec sddsprocess /home/helios/oagData/sr/BPMStatus/config.sdds -filter=col,NonexistentH,1,1 -pipe=out \
    | sdds2stream -pipe -col=DeviceName]
set vmissingBpms [exec sddsprocess /home/helios/oagData/sr/BPMStatus/config.sdds -filter=col,NonexistentV,1,1 -pipe=out \
    | sdds2stream -pipe -col=DeviceName]

set hmissingCorrs [exec sddsprocess /home/helios/oagData/sr/HCorrectorStatus/config.sdds -filter=col,Nonexistent,1,1 -pipe=out \
    | sdds2stream -pipe -col=DeviceName]
set vmissingCorrs [exec sddsprocess /home/helios/oagData/sr/VCorrectorStatus/config.sdds -filter=col,Nonexistent,1,1 -pipe=out \
    | sdds2stream -pipe -col=DeviceName]

set hmissingList [concat $hmissingBpms S7A:P0 $hmissingCorrs]
set vmissingList [concat $vmissingBpms S7A:P0 $vmissingCorrs]

set hmissingList ""
set vmissingList ""
#if [file exist $outputDir/h.default/config] {
#    set hConfigDesc [lindex [exec sdds2stream -par=Description $outputDir/h.default/config] 0]
#} else {
#    set vconfigDesc ""
#}
#if [file exist $outputDir/v.default/config] {
#    set vConfigDesc [lindex [exec sdds2stream -par=Description $outputDir/v.default/config] 0]
#} else {
#    set vConfigDesc ""
#}

set tmpRoot /tmp/[APSTmpString]
foreach plane {Horizontal Vertical} pl {h v} {
    if [catch {exec sddsprocess /home/helios/oagData/sr/feedbackSimulation/bpmDataConfig.sdds $tmpRoot.$pl \
        -match=col,Directory=*${plane}* } result] {
            puts stderr $result
        exit 1
    }
    set ${pl}bpmDataDirList [exec sdds2stream -col=Directory $tmpRoot.$pl]
    set ${pl}bpmLatticeList [exec sdds2stream -col=Lattice $tmpRoot.$pl]
    set ${pl}bpmTurnsList [exec sdds2stream -col=Turns $tmpRoot.$pl]
}

file delete -force $tmpRoot.h $tmpRoot.v

#set bpmDataDirList [exec sdds2stream -col=Directory /home/helios/oagData/sr/feedbackSimulation/bpmDataConfig.sdds]
#set bpmLatticeList [exec sdds2stream -col=Lattice /home/helios/oagData/sr/feedbackSimulation/bpmDataConfig.sdds]
#set bpmTurnsList  [exec sdds2stream -col=Turns /home/helios/oagData/sr/feedbackSimulation/bpmDataConfig.sdds]

set hconfig h.default
set vconfig v.default
APSApplication . -name SRCorrNoiseModel -version 1 \
  -overview {This application generates corrector noise data from collected FPGA bpm data.}

set win .userFrame

set w1List [APSTabFrame .tabs -parent .userFrame -width 1350 -height 950 -labelList "Horizontal Vertical" -label ""]
CreateCorrNoiseModelWidget -plane h -parent [lindex $w1List 0]
CreateCorrNoiseModelWidget -plane v -parent [lindex $w1List 1]

#SelectDataDirectory -index 0 

