#!/bin/sh
# \
exec oagwish "$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 CVSRevisionAuthor "\Revision 1.0 $ \$Author: Shang $"
set appName "RTFB Response Matrix measurement (Integral)"

set env(EPICS_CA_ADDR_LIST) "ctlsdaqsrv1 iocrtfbdaq ctlsdaqdev2 ctlsdaqdev1.aps4.anl.gov"
set env(EPICS_CA_MAX_ARRAY_BYTES) 1048576


set refDir /home/helios/oagData/sr/rtfeedback/monitorFiles
set modelDir /home/helios/oagData/sr/rtfeedback/lattices/default
set VModelDir v.default
set HModelDir h.2017-0619.00
set HModelDir h.2018-0523.00
set VModelDir v.2018-0523.00
set outputDir [APSGoToDailyDirectory -subdirectory S27IntegratedStudies]
#set outputDir /home/helios/SR/daily/2017/06/19/2/S27IntegratedStudies/SineData
set outputDir /home/helios/SR/daily/2017/07/17/3/S27IntegratedStudies/Closed_Loop_RespMeasurement
set outputDir .
set outputDir /home/helios/SR/daily/2017/09/28/2/S27IntegratedStudies/integral
set outputDir .
#set outputDir  /home/helios/SR/daily/2017/09/28/2/S27IntegratedStudies/integral
#set outputDir /home/helios/SR/daily/2017/10/09/3/S27IntegratedStudies
#set outputDir /home/helios/SR/daily/2018/05/23/3/S27IntegratedStudies

set corr S27A:H3
#set fileName ${corr}_Sine_44Hz_5Amp
set CurrentAmp 5.0
set interval 1.2
set steps 10
set plane H
set status ""
set index 0
set alpha 0.1
set freq 44
set monDir /home/helios/oagData/sr/rtfeedback/monitorFiles
proc SetStatus {text} {
    global status
    set status "[exec date] $text"
    update
}

set BPMList {S27A:P0 S27A:P2 S27A:P3 S27A:P4 S27B:P4 S27B:P3 S27B:P2 S27B:P0 S28A:P0 S28A:P2 S28A:P3 S28A:P4 S28B:P4 S28B:P3 S28B:P2 S28B:P0}
proc processDataWithNAFFNew {args} {
    global OAGGlobal
    set filename ""
    set corr ""
    APSParseArguments {corr filename}
    global CurrentAmp outputDir BPMList
    
    set pars [exec sddsquery -par $filename]
    if [lsearch -exact $pars "CorrectorCurrent"]<0 {
        set current $CurrentAmp
    } else {
        set current [lindex [exec sdds2stream -par=CorrectorCurrent $filename] 0]
        }
    if [regexp "H" $corr] {
        set coord X
    } else {
        set coord Y
    }
    set sinFreq [lindex [exec sdds2stream -par=SineFreq $filename] 0]
    #filter the frequency after naff result to make sure the fundmental frequency is being used
    
    set rootname [file root [file root $filename]]
    set index [scan $filename $rootname.sdds.%ld]
    SetStatus "processing $filename..."
    set findex [format %02d $index]
    set tmpRoot /tmp/[APSTmpString]
    if [catch {exec sddssplit $filename -rootname=$tmpRoot -digits=3 } result] {
        return -code error "processDataWithNaffNew0: $result"
    }
    set files [glob ${tmpRoot}*.sdds]
    set fileList ""
    set freq0 [expr $sinFreq - 5.0]
    set freq1 [expr $sinFreq + 5.0]
    set i 0
    foreach file $files {
        incr i
        set fileList1 ""
        set error 0
        SetStatus "processing page $i..."
        foreach bpm $BPMList {
            set error 0
            SetStatus "processing $bpm ..."
            if [catch {exec sddsnaff $file -col=Time,U*${bpm}${coord}*LongErrorHistAM -pipe=out \
                         | sddsconvert -pipe -edit=col,U*,%/U://%/${coord}:OFB:LongErrorHistAM// \
                         | sddsprocess -pipe=in $tmpRoot.$bpm -filter=col,${bpm}Frequency,$freq0,$freq1 } result] {
                SetStatus "Error processing $bpm in page $i (no fundmental frequency found) :$result"
                set error 1
                break
            } else {
                lappend fileList1 $tmpRoot.$bpm
            }
        }
        if $error {
            continue
        }
        if [catch {eval exec sddsxref $fileList1 $tmpRoot.$i -take=S* } result] {
            return -code error  "processDataWithNaffNew1: $result"
        }
        lappend fileList $tmpRoot.$i
    }
     puts $fileList
    if [catch {eval exec sddscombine $fileList -pipe=out \
                 |  sddscollect -pipe -col=suffix=Amplitude,col=Amplitude -col=suffix=Phase,col=Phase \
                 -col=suffix=Frequency,col=Frequency -col=suffix=Significance,col=Significance \
                 | tee $filename.naff \
                 | sddsprocess -pipe \"-define=col,Real,Amplitude Phase sin *\" \"-define=col,Imag,Amplitude Phase cos *\" \
                 | sddsenvelope -pipe -mean=Real,Imag -copy=Rootname  \
                 | sddsprocess -pipe \"-redefine=col,Real,RealMean $current /\" \"-redefine=col,Imag,ImagMean $current /\" \
                 | sddsconvert -pipe -rename=col,Rootname=BPMName \
                 | sddsxref -pipe $OAGGlobal(SRLatticesDirectory)/default/aps.twi  -nowarnings -take=s -match=BPMName=ElementName \
                 | sddssort -pipe -col=s \
                 | tee ${rootname}.measrm.$findex \
                 | sddsconvert -pipe -rename=col,Real=$corr \
                 | sddsconvert -pipe=in ${rootname}.mrm.$findex -retain=col,BPMName,$corr } result] {
        return -code error "processDataWithNAFFNew3: $result"
    }
    return
}

proc processDataWithNAFF {args} {
    global OAGGlobal
    set filename ""
    set corr ""
    APSParseArguments {corr filename}
    global CurrentAmp outputDir indepCol
    
    set pars [exec sddsquery -par $filename]
    if [lsearch -exact $pars "CorrectorCurrent"]<0 {
        set current $CurrentAmp
    } else {
        set current [lindex [exec sdds2stream -par=CorrectorCurrent $filename] 0]
        }
    if [regexp "H" $corr] {
        set coord X
    } else {
        set coord Y
    }
    set rootname [file root [file root $filename]]
    set index [scan $filename $rootname.sdds.%ld]
    SetStatus "processing $filename..."
    set findex [format %02d $index]
    if [catch {exec sddsnaff $filename -pipe=out -col=$indepCol,U*P*${coord}*LongErrorHistAM \
                 -terminateSearch=freq=3 \
                 | sddsprocess -pipe -clip=1,0,invert \
                 | sddscollect -pipe -col=suffix=Amplitude,col=Amplitude -col=suffix=Phase,col=Phase \
                 -col=suffix=Frequency,col=Frequency -col=suffix=Significance,col=Significance \
                 | tee $filename.naff \
                 | sddsprocess -pipe "-define=col,Real,Amplitude Phase sin *" "-define=col,Imag,Amplitude Phase cos *" \
                 "-edit=col,BPMName,Rootname,%/U://%/X:OFB:LongErrorHistAM//" \
                 | sddsenvelope -pipe -mean=Real,Imag -copy=BPMName \
                 | sddsprocess -pipe "-redefine=col,Real,RealMean $current /" "-redefine=col,Imag,ImagMean $current /" \
                 | sddsxref -pipe $OAGGlobal(SRLatticesDirectory)/default/aps.twi  -nowarnings -take=s -match=BPMName=ElementName \
                 | sddssort -pipe -col=s \
                 | tee ${rootname}.measrm.R$findex \
                 | sddsconvert -pipe -rename=col,Real=$corr \
                 | sddsconvert -pipe=in ${rootname}.mrm.R$findex -retain=col,BPMName,$corr } result] {
        return -code error "processDataWithNAFF: $result"
    }
    return
}

set useImag 0
set window 0
proc processDataWithFFT {args} {
    set filename ""
    set corr ""
    APSParseArguments {corr filename}
    global CurrentAmp outputDir window indepCol useImag OAGGlobal
    
    set pars [exec sddsquery -par $filename]
    if [lsearch -exact $pars "CorrectorCurrent"]<0 {
        set current $CurrentAmp
    } else {
        set current [lindex [exec sdds2stream -par=CorrectorCurrent $filename] 0]
    }
    if [regexp "H" $corr] {
        set coord X
    } else {
        set coord Y
    }
    set sinFreq [lindex [exec sdds2stream -par=SineFreq $filename] 0]
    set f1 [expr $sinFreq - 5.0]
    set f2 [expr $sinFreq + 5.0]
    
    set rootname [file root [file root $filename]]
    set index [scan $filename $rootname.sdds.%ld]
    SetStatus "processing $filename..."
    set findex [format %02d $index]
    
    if $useImag {
        set opt "-redefine=col,$corr,${corr}_Imag,units=mm/Amps"
    } else {
        set opt  "-redefine=col,$corr,Amplitude Sign * $current /,units=mm/Amps" 
    }
 #   puts $opt
    #change the processing method, do fft first and average
    if [catch {eval exec sddsfft $filename -pipe=out -col=Index,U*P*${coord}*LongErrorHistAM \
                 -psdOutput=plain -fullOutput -supp  \
                 | tee $filename.fft \
                 | sddsprocess -pipe \
                 -process=FFT*${coord}*,maximum,%s_Max \
                 -process=FFT*${coord}*,maximum,%s_Max_Arg,functionOf=Arg%s,position \
                 -process=FFT*${coord}*,maximum,%s_Max_Real,functionof=Real%s,position \
                 -process=FFT*${coord}*,maximum,%s_Max_Imag,functionof=Imag%s,position \
                 | sddsconvert -pipe -del=col,* \
                  -retain=param,*Max,*Arg,*Real,*Imag \
                 | sddsconvert -pipe \
                 -edit=param,FFTU*,%/FFTU://%/${coord}:OFB:LongErrorHistAM// \
                 | sddscollapse -pipe \
                 | sddsprocess -pipe -process=S*,ave,%sMean \
                 | sddscollapse -pipe \
                 | sddscollect -pipe  -col=suffix=_MaxMean,col=Amplitude -col=suffix=_Max_ArgMean,col=Arg \
                 -col=suffix=_Max_RealMean,col=${corr}_Real -col=suffix=_Max_ImagMean,col=${corr}_Imag \
                 | sddsprocess -pipe \
                 -reprint=par,Corrector,$corr \
                 | sddsxref -pipe $OAGGlobal(SRLatticesDirectory)/default/aps.twi  -nowarnings -take=s -match=Rootname=ElementName \
                 | sddssort -pipe -col=s \
                 | sddsconvert -pipe -rename=col,Rootname=BPMName  -del=col,s,Column \
                 | sddsprocess -pipe \"-redefine=col,${corr}_Real,${corr}_Real $current /\" \
                 \"-redefine=col,${corr}_Imag,${corr}_Imag $current /\" \
                 \"-define=col,Sign,${corr}_Imag 0 > ? 1 : -1 $\" \
                 | sddsprocess -pipe \"$opt\" \
                 \"-redefine=par,CorrectorCurrent,$current,units=Amps\" \
                 | tee ${rootname}.measrm.R$findex  \
                 | sddsconvert -pipe=in -retain=col,BPMName,$corr \
                 ${rootname}.mrm.R$findex } result] {
        return -code error "Error in  processing data (FFT1): $result"
    }
    #process corrector data
    if [catch {exec sddsfft $filename -pipe=out -col=Index,U*H* -supp -fullOutput \
                 | sddsprocess -pipe -process=FFT*H*,max,%sMax \
                 -process=FFT*H*,max,%sImag,functionof=Imag%s,position \
                 -process=FFT*H*,max,%sReal,functionof=Real%s,position \
                 | sddscollapse -pipe \
                 | sddsprocess -pipe -process=*Max,ave,%sMean \
                 -process=*Imag,ave,%sMean -process=*Real,ave,%sMean \
                 | sddscollapse -pipe \
                 | sddscollect -pipe -col=suffix=MaxMean,col=Mean -col=suffix=ImagMean,col=Imag -col=suffix=RealMean,col=Real \
                 | sddsprocess -pipe "-match=col,Rootname=*H3*Error*,Rootname=*H4*Error*,|" \
                 | sddsprocess -pipe -reedit=col,Rootname,%/FFTU://%/:OFB:LongErrorHistAM// \
                 "-define=col,Sign,Imag 0 > ? 1 : -1 $ " \
                 | sddsprocess -pipe "-redefine=col,Mean1,Mean Sign * $current /" \
                 | sddsprocess -pipe \
                 "-redefine=col,$corr,Rootname \"$corr\" streq ? 1.0 Mean1 - : Mean1 $ " \
                 | tee $filename.proc1 \
                 | sddsconvert -pipe=in $filename.proc -retain=col,$corr } result] {
        return -code error "Error processing corrector data: $result"
    }
    
    SetStatus "done ."
    return
}

proc processDataWithFFTOld {args} {
    set filename ""
    set corr ""
    APSParseArguments {corr filename}
    global CurrentAmp outputDir OAGGlobal
    
    set pars [exec sddsquery -par $filename]
    if [lsearch -exact $pars "CorrectorCurrent"]<0 {
        set current $CurrentAmp
    } else {
        set current [lindex [exec sdds2stream -par=CorrectorCurrent $filename] 0]
    }
    if [regexp "H" $corr] {
        set coord X
    } else {
        set coord Y
    }
    set rootname [file root [file root $filename]]
    set index [scan $filename $rootname.sdds.%ld]
    SetStatus "processing $filename..."
    set findex [format %02d $index]
    #change the processing method, do fft first and average
    if [catch {exec sddsfft $filename -col=Time,U*P*${coord}*LongErrorHistAM -psdOutput=plain -fullOutput -pipe=out \
                 | sddsprocess -pipe \
                 "-redefine=col,%s,%s abs,select=FFT*${coord}*" \
                 | sddsprocess -pipe \
                 -process=FFT*${coord}*,maximum,%s_Max \
                 -process=FFT*${coord}*,maximum,%s_Max_Arg,functionOf=Arg%s,position \
                 -process=FFT*${coord}*,maximum,%s_Max_Real,functionof=Real%s,position \
                 -process=FFT*${coord}*,maximum,%s_Max_Imag,functionof=Imag%s,position \
                 | sddsprocess -pipe \
                 "-redefine=param,%s_rm,%s $current /,units=mm/Amp,select=FFT*${coord}*_Max" \
                 | sddsconvert -pipe \
                 -delete=col,* \
                 -delete=param,* -retain=param,FFT*_Max_rm,*Arg,*Real,*Imag \
                 | sddsconvert -pipe \
                 -edit=param,FFTU*,%/FFTU://%/${coord}:OFB:LongErrorHistAM_Max//%/_rm/_bpm/%/_Arg/_arg/%/_Real/_real/%/_Imag/_imag/ \
                 | sddscollapse -pipe \
                 | sddsprocess -pipe -process=S*,ave,%sMean \
                 | sddscollapse -pipe \
                 | sddscollect -pipe -col=suffix=_bpmMean,col=$corr -col=suffix=_argMean,col=Arg \
                 -col=suffix=_realMean,col=${corr}_Real -col=suffix=_imagMean,col=${corr}_Imag \
                 | sddsprocess -pipe \
                 -reprint=par,Corrector,$corr \
                 -redefine=col,$corr,$corr,units=mm/A \
                 | sddsxref -pipe $OAGGlobal(SRLatticesDirectory)/default/aps.twi  -nowarnings -take=s -match=Rootname=ElementName \
                 | sddssort -pipe -col=s \
                 | sddsconvert -pipe -rename=col,Rootname=BPMName  -del=col,s,Column \
                 | sddsprocess -pipe "-redefine=col,${corr}_Real,${corr}_Real $current /" \
                 "-redefine=col,${corr}_Imag,${corr}_Imag $current /" \
                 "-redefine=col,AbsArg,Arg abs" \
                 | sddsprocess -pipe \
                 "-redefine=col,signValue,AbsArg 90 > ? -1.0 : 1.0 $ " \
                 "-redefine=par,CorrectorCurrent,$current,units=Amps" \
                 | tee ${rootname}.measrm.$findex  \
                 | sddsconvert -pipe -del=col,$corr \
                 | sddsconvert -pipe -rename=col,${corr}_Real=$corr \
                 | sddsconvert -pipe=in -retain=col,BPMName,$corr \
                 ${rootname}.mrm.$findex } result] {
        return -code error "Error in  processing data (FFT): $result"
    }
                 
    SetStatus "done ."
    
    return
}

proc processDataWithSVD {args} {
    set filename ""
    set corr ""
    APSParseArguments {corr filename}
    global CurrentAmp outputDir OAGGlobal
    
    set pars [exec sddsquery -par $filename]
    if [lsearch -exact $pars "CorrectorCurrent"]<0 {
        set current $CurrentAmp
    } else {
        set current [lindex [exec sdds2stream -par=CorrectorCurrent $filename] 0]
    }
    if [regexp "H" $corr] {
        set coord X
    } else {
        set coord Y
    }
    set rootname [file root [file root $filename]]
    set index [scan $filename $rootname.sdds.%ld]
    SetStatus "processing $filename..."
    set findex [format %02d $index]
    #change the processing method, do fft first and average
    if [catch {exec sddsfft $filename -col=Time,U*P*${coord}*LongErrorHistAM -psdOutput=plain -fullOutput -pipe=out \
                 | sddsprocess -pipe \
                 "-redefine=col,%s,%s abs,select=FFT*${coord}*" \
                 | sddsprocess -pipe \
                 -process=FFT*${coord}*,maximum,%s_Max \
                 -process=FFT*${coord}*,maximum,%s_Max_Arg,functionOf=Arg%s,position \
                 -process=FFT*${coord}*,maximum,%s_Max_Real,functionof=Real%s,position \
                 -process=FFT*${coord}*,maximum,%s_Max_Imag,functionof=Imag%s,position \
                 | sddsprocess -pipe \
                 "-redefine=param,%s_rm,%s $current /,units=mm/Amp,select=FFT*${coord}*_Max" \
                 | sddsconvert -pipe \
                 -delete=col,* \
                 -delete=param,* -retain=param,FFT*_Max_rm,*Arg,*Real,*Imag \
                 | sddsconvert -pipe \
                 -edit=param,FFTU*,%/FFTU://%/${coord}:OFB:LongErrorHistAM_Max//%/_rm/_bpm/%/_Arg/_arg/%/_Real/_real/%/_Imag/_imag/ \
                 | sddscollapse -pipe \
                 | sddsprocess -pipe -process=S*,ave,%sMean \
                 | sddscollapse -pipe \
                 | sddscollect -pipe -col=suffix=_bpmMean,col=$corr -col=suffix=_argMean,col=Arg \
                 -col=suffix=_realMean,col=${corr}_Real -col=suffix=_imagMean,col=${corr}_Imag \
                 | sddsprocess -pipe \
                 -reprint=par,Corrector,$corr \
                 -redefine=col,$corr,$corr,units=mm/A \
                 | sddsxref -pipe $OAGGlobal(SRLatticesDirectory)/default/aps.twi  -nowarnings -take=s -match=Rootname=ElementName \
                 | sddssort -pipe -col=s \
                 | sddsconvert -pipe -rename=col,Rootname=BPMName  -del=col,s,Column \
                 | sddsprocess -pipe "-redefine=col,${corr}_Real,${corr}_Real $current /" \
                 "-redefine=col,${corr}_Imag,${corr}_Imag $current /" \
                 "-redefine=col,AbsArg,Arg abs" \
                 | sddsprocess -pipe \
                 "-redefine=col,signValue,AbsArg 90 > ? -1.0 : 1.0 $ " \
                 "-redefine=par,CorrectorCurrent,$current,units=Amps" \
                 | tee ${rootname}.measrm.R$findex  \
                 | sddsconvert -pipe -del=col,$corr \
                 | sddsconvert -pipe -rename=col,${corr}_Imag=$corr \
                 | sddsconvert -pipe=in -retain=col,BPMName,$corr \
                 ${rootname}.mrm.R$findex } result] {
        return -code error "Error in  processing data (FFT): $result"
    }
                 
    SetStatus "done ."
    
    return
}


proc ProcessData {args} {
    set filename ""
    set corr ""
    APSParseArguments {corr filename}
    global CurrentAmp outputDir OAGGlobal
    
    set pars [exec sddsquery -par $filename]
    if [lsearch -exact $pars "CorrectorCurrent"]<0 {
        set current $CurrentAmp
    } else {
        set current [lindex [exec sdds2stream -par=CorrectorCurrent $filename] 0]
    }
    if [regexp "H" $corr] {
        set coord X
    } else {
        set coord Y
    }
    set rootname [file root [file root $filename]]
    set index [scan $filename $rootname.sdds.%ld]
    SetStatus "processing $filename..."
    set findex [format %02d $index]
    #average data first, then do fft
    
    if [catch {exec sddsbreak $filename -pipe=out \
                 -decreaseOf=Index \
                 | sddsenvelope -pipe=in $rootname.env.$findex \
                 -mean=* } result] {
        return -code error "Error processing data1: $result"
    }
    if [catch {exec sddsfft ${rootname}.env.$findex ${rootname}.env.fft.$findex \
                 -col=TimeMean,U*P*${coord}*LongErrorHistAMMean -psdOutput=plain -fullOutput } result] {
        return -code error "Error processing data2: $result"
    }
    if [catch {exec sddsprocess -pipe=out ${rootname}.env.fft.$findex \
                 -process=FFT*${coord}*,maximum,%s_Max \
                 -process=FFT*${coord}*,maximum,%s_Max_Arg,functionOf=Arg%s,position \
                 -process=FFT*${coord}*,maximum,%s_Max_Real,functionof=Real%s,position \
                 -process=FFT*${coord}*,maximum,%s_Max_Imag,functionof=Imag%s,position \
                 | sddsprocess -pipe \
                 "-redefine=param,%s_rm,%s $current /,units=mm/Amp,select=FFT*${coord}*_Max" \
                 | sddsconvert -pipe \
                 -delete=col,* \
                 -delete=param,* -retain=param,FFT*_Max_rm,*Arg,*Real,*Imag \
                 | sddsconvert -pipe \
                 -edit=param,FFTU*,%/FFTU://%/${coord}:OFB:LongErrorHistAMMean_Max//%/_rm/_bpm/%/_Arg/_arg/%/_Real/_real/%/_Imag/_imag/ \
                 | tee tt1 \
                 | sddscollapse -pipe \
                 | sddscollect -pipe -col=suffix=_bpm,col=$corr -col=suffix=_arg,col=Arg \
                 -col=suffix=_real,col=${corr}_Real -col=suffix=_imag,col=${corr}_Imag \
                 | sddsprocess -pipe \
                 -reprint=par,Corrector,$corr \
                 -redefine=col,$corr,$corr,units=mm/A \
                 | sddsxref -pipe $OAGGlobal(SRLatticesDirectory)/default/aps.twi  -nowarnings -take=s -match=Rootname=ElementName \
                 | sddssort -pipe -col=s \
                 | sddsconvert -pipe -rename=col,Rootname=BPMName  -del=col,s,Column \
                 | sddsprocess -pipe "-redefine=col,${corr}_Real,${corr}_Real $current /" \
                 "-redefine=col,${corr}_Imag,${corr}_Imag $current /" \
                 "-redefine=col,AbsArg,Arg abs" \
                 | sddsprocess -pipe \
                 "-redefine=col,signValue,AbsArg 90 > ? -1.0 : 1.0 $ " \
                 "-redefine=par,CorrectorCurrent,$current,units=Amps" \
                 | tee ${rootname}.measrm.$findex  \
                 | sddsconvert -pipe -del=col,$corr \
                 | sddsconvert -pipe -rename=col,${corr}_Real=$corr \
                 | sddsconvert -pipe=in -retain=col,BPMName,$corr \
                 ${rootname}.mrm.$findex } result] {
        return -code error "Error in collecting data5: $result"
    }
    SetStatus "done ."
    return
}

proc CollectDataByCorrector  {args } {
    set corr ""
    set rootname ""
    APSParseArguments {corr rootname} 
    global outputDir CurrentAmp monDir interval steps  Sign plane index freq method useImag
    
    set freq0 [expr int(ceil($freq))]
    
    set fileName $outputDir/${rootname}-$corr
    if ![string length $Sign] {
        return -code error "Please update the perturb frequency first."
    }
    
    switch $plane {
        H {
            set coord X
        }
        V {
            set coord Y
        }
    }
    set findex [format %02d $index]
    
    set sampleRate [exec cavget -list=U:S27:OFB:DSP:LoopRateM -repeat=number=15,pause=0.3,average]
    SetStatus "Sample Rate for 15 averages = ${sampleRate} Hz"
    
    if [catch {exec sddswmonitor $monDir/FBCstepFile.wmon ${fileName}.sdds.$findex -scalars=$monDir/FBC.mon \
        -interval=$interval -steps=$steps -verbose -erase } result] {
        SetStatus "Error collecting data1: $result"
        return
    }
    SetStatus "collecting data for $corr ..."
    
    if [catch {exec sddsprocess ${fileName}.sdds.$findex "-redefine=col,Time,Index ${sampleRate} /,units=s" -nowarnings \
                 -redefine=par,SineFreq,$freq \
                 -redefine=par,CorrectorCurrent,$CurrentAmp,units=Amps } result] {
        SetStatus "Error collecting data2: $result"
        return
    }
   # set useImag 1
    if [catch {processDataWithFFT -filename ${fileName}.sdds.$findex  -corr $corr } result] {
        return -code error "Error proessing data for $corr: $result"
    }
    #process corrector matrix
    return
}

proc StepResponseMeasurement {args} {
    global outputDir index plane AFG modelDir currentAmp
    
    
    if [catch {exec cavput -list=U:S27:OFB:${AFG}:EnableC=1 -pend=20 } result] {
        SetStatus "Error setting U:S27:OFB:${AFG}:EnableC to waveform : $result"
        return
    }
    if [catch {exec cavput -list=U:S27:OFB:AFG1:DeltaC=$currentAmp -pend=20 } result] {
        return -code error "Error settting U:S27:OFB:AFG1:DeltaC=$currentAmp : $result"
    }
    switch $plane {
        H {
            set val 0
        }
        V {
            set val 1
        }
    }
    if [catch {exec cavput -list=U:S27:OFB:${AFG}:PlaneC=$val -pend=20} result] {
        SetStatus "Error changing plane: $result"
        return
    }
    set corrList [list S27A:${plane}3 S27B:${plane}4 S28A:${plane}3 S28B:${plane}4]
    set selectList {1 2 5 6}
    foreach corr $corrList sel $selectList {
        SetStatus "Change corrector to $corr..."
        if [catch {exec cavput -list=U:S27:OFB:${AFG}:SignalIndex2C=$sel -pend=30} result] {
            SetStatus "Error in changing corrector: $result"
            return
        }
        if [catch {CollectDataByCorrector -corr $corr -rootname Step}  result] {
            SetStatus "Error collecting data for $corr : $result"
            return
        }
    }
    SetStatus "compute step response ..."
    if [catch {CalculateStepResponse -rootname Step} result] {
        SetStatus "Error in computing step response matrix: $result"
        return
    }
    SetStatus "done."
}

proc Start {args} {
    global outputDir index plane AFG modelDir S27A3 S27B4 S28A3 S28B4 rootname freqLoaded
    
    if {$index==0} {
        if !$freqLoaded {
            # load perturbation waveform once 
            SetStatus "compute and load perturb frequency waveform..."
            if [catch {ComputeFrequency -load 1} result] {
                SetStatus "Error in updating perturb frequency waveform : $result"
                return
            }
        }
        if [catch {exec cavput -list=U:S27:OFB:${AFG}:EnableC=2 -pend=20 } result] {
            SetStatus "Error setting U:S27:OFB:${AFG}:EnableC to waveform : $result"
            return
        }
    }
    switch $plane {
        H {
            set val 0
        }
        V {
            set val 1
        }
    }
    if [catch {exec cavput -list=U:S27:OFB:${AFG}:PlaneC=$val -pend=20} result] {
        SetStatus "Error changing plane: $result"
        return
    }
    if {0} {
        SetStatus "Load IRM into ioc..."
        if [catch {LoadIRM } result] {
            SetStatus "Error loading IRM into IOC: $result"
            return
        }
    }
    SetStatus "start measurement index=$index ..."
    set corrList [list S27A:${plane}3 S27B:${plane}4 S28A:${plane}3 S28B:${plane}4]
    set varList {S27A3 S27B4 S28A3 S28B4}
    set selectList {1 2 5 6}
    if ![string length $rootname] {
        set rootname [clock format [clock seconds] -format %Y:%m%d:%H%M%S]
    }
    cd $outputDir
    foreach corr $corrList sel $selectList var $varList {
       # if ![set $var] {
       #     continue
       # }
        set abort 0
        SetStatus "Change corrector to $corr..."
        if [catch {exec cavput -list=U:S27:OFB:${AFG}:SignalIndex2C=$sel -pend=30} result] {
            SetStatus "Error in changing corrector: $result"
            return
        }
        set filename ${rootname}${corr}.sdds.[format %02d $index]
        if [file exist $filename] {
            if ![APSYesNoPopUp "$filename already exist, overwrite it?"] {
                SetStatus "$filename already, create new rootname to avoid overwrite it."
                set rootname [clock format [clock seconds] -format %Y-%m%d:%H%M%S]
            }
        }
        if [catch {CollectDataByCorrector -corr $corr -rootname $rootname}  result] {
            SetStatus "Error collecting data for $corr : $result"
            return
        }
    }
    SetStatus "compute new model matrix ..."
    if [catch {CalculateMachineResponse -rootname $rootname} result] {
        SetStatus "Error in computing new model matrix: $result"
        return
    }
    catch {UpdatenameDatabase}
    SetStatus "Resp delta measure (index=$index) done."
   # incr index
}

proc UpdateRootnameDatabase {args} {
    global rootname outputDir
    cd $outputDir
    set filename rootname.sdds
    set tmpRoot /tmp/[APSTmpString]
    if [catch {exec sddsmakedataset -col=Rootname,type=string -data=$rootname $tmpRoot.root } result] {
        return -code error "$result"
    }
    if [file exist $filename] {
        if [catch {exec sddscombine $filename $tmpRoot -merge -pipe=out \
                     | sddssort -pipe=in $filename -col=Rootname } result] {
            return -code error $result
        }
    } else {
        exec cp $tmpRoot.root $filename
    }
}

proc GetRootname {args} {
    global outputDir rootname
    cd $outputDir
    if ![file exist rootname.sdds] {
        SetStatus "no data"
        return
    }
    set rootnameList [exec sdds2stream -col=Rootname rootname.sdds]
    APSScrolledListWindow .root -name "Select a rootname" \
      -label "Select a rootname" -itemList [join $rootnameList] \
      -selectionVar rootname
    tkwait variable rootname
    return $rootname
}

proc LoadIRM1 {args} {
    set plot 0
    APSParseArguments {plot}
    global rootname plane outputDir
    cd $outputDir
    
    set IRM $rootname.irm
    
    if ![file exist $IRM] {
        return -code error "Error: irm matrix $IRM does not exist!"
    }
    
    set irmPV  U:S27:OFB:${plane}:Irm16x8AC
    if [catch {exec sddswget prevIRM.sdds -pvname=$irmPV } result] {
        return -code error "Error reading $irmPV: $result"
    }
    set matrixFile $rootname.matrix
    set corrList [list S27A:${plane}2 S27A:${plane}3 S27B:${plane}4 S27B:${plane}2 S28A:${plane}2 S28A:${plane}3 S28B:${plane}4 S28B:${plane}2]
    if [catch {exec sddstranspose $IRM  -pipe=out \
                 | sddsprocess -pipe=in  $matrixFile  "-redefine=col,S27A:${plane}2,0" \
                 "-redefine=col,S27B:${plane}2,0" \
                 "-redefine=col,S28A:${plane}2,0" \
                 "-redefine=col,S28B:${plane}2,0" } result] {
        return -code error "Error processing matrix file: $result"
    }
    set fileList ""
    set tmpRoot /tmp/[APSTmpString]
    foreach corr $corrList {
        if [catch {exec sddsconvert $matrixFile -retain=col,$corr -pipe=out \
                     | sddsconvert -pipe=in $tmpRoot.$corr -rename=col,$corr=Waveform } result] {
            return -code error "Error $corr data not found: $result"
        }
        lappend fileList $tmpRoot.$corr
    }
    if [catch {eval exec sddscombine $fileList -merge -pipe=out \
                 | sddsprocess -pipe=in $matrixFile.load -redefine=col,Index,i_row,type=long \
                 "-redefine=col,Waveform,Waveform,type=float" \
                 -reprint=par,WaveformPV,$irmPV } result] {
        return -code error "Error generating waveform file: $result"
    }
    
    #LOAD 
    if [catch {exec sddswput $matrixFile.load -pend=30} result] {
        return -code error "Error loading matrix into IOC: $result"
    }
    if $plot {
        exec sddsplot -grap=sym,conn,vary=sub  "-ylabel=Matrix element(mm/A)" -col=Index,Waveform "-leg=spec=previous  matrix" prevIRM.sdds \
          -col=Index,Waveform "-leg=spec=matrix just loaded"  $matrixFile.load  &
    }

}

proc LoadIRM {args} {
    set plot 0
    APSParseArguments {plot}
    global index modelDir outputDir plane S27A3 S27B4 S28A3 S28B4 HModelDir VModelDir rootname
    cd $outputDir
    
    set prevIndex [expr $index - 1]
    set findex [format %02d $index]
    set fprevIndex [format %02d $prevIndex]
    
    if {$index==0} {
        set IRM $modelDir/[set ${plane}ModelDir]/irm
    } else {
        set IRM $outputDir/$rootname$plane.machine.R$fprevIndex.irm
    }
    if ![file exist $IRM] {
        return -code error "Error: irm matrix $IRM does not exist!"
    }
    
    set irmPV  U:S27:OFB:${plane}:Irm16x8AC
    if [catch {exec sddswget prev_irm$findex.sdds -pvname=$irmPV } result] {
        return -code error "Error reading $irmPV: $result"
    }
    set matrixFile irm$findex.matrix
    set corrList [list S27A:${plane}2 S27A:${plane}3 S27B:${plane}4 S27B:${plane}2 S28A:${plane}2 S28A:${plane}3 S28B:${plane}4 S28B:${plane}2]
    if [catch {exec sddstranspose $IRM  -pipe=out \
                 | sddsprocess -pipe=in  $matrixFile  "-redefine=col,S27A:${plane}2,0" \
                 "-redefine=col,S27B:${plane}2,0" \
                 "-redefine=col,S28A:${plane}2,0" \
                 "-redefine=col,S28B:${plane}2,0" } result] {
        return -code error "Error processing matrix file: $result"
    }
    set fileList ""
    set tmpRoot /tmp/[APSTmpString]
    foreach corr $corrList {
        if [catch {exec sddsconvert $matrixFile -retain=col,$corr -pipe=out \
                     | sddsconvert -pipe=in $tmpRoot.$corr -rename=col,$corr=Waveform } result] {
            return -code error "Error $corr data not found: $result"
        }
        lappend fileList $tmpRoot.$corr
    }
    if [catch {eval exec sddscombine $fileList -merge -pipe=out \
                 | sddsprocess -pipe=in $matrixFile.load -redefine=col,Index,i_row,type=long \
                 "-redefine=col,Waveform,Waveform,type=float" \
                 -reprint=par,WaveformPV,$irmPV } result] {
        return -code error "Error generating waveform file: $result"
    }
    
    #LOAD 
    if [catch {exec sddswput $matrixFile.load -pend=30} result] {
        return -code error "Error loading matrix into IOC: $result"
    }
    if $plot {
        exec sddsplot -grap=sym,conn,vary=sub  "-ylabel=Matrix element(mm/A)" -col=Index,Waveform "-leg=spec=previous  matrix" prev_irm$findex.sdds \
          -col=Index,Waveform "-leg=spec=matrix just loaded"  $matrixFile.load  &
    }
}

proc CalculateStepResponse {args} {
   
    global plane outputDir CurrentAmp modelDir Sign index alpha
    cd $outputDir
    set corrList [list S27A:${plane}3 S27B:${plane}4 S28A:${plane}3 S28B:${plane}4]
    set fileList ""
    set findex [format %02d $index]
    foreach corr $corrList {
        set filename ${corr}.mrm.$findex
        if ![file exist $filename] {
            SetStatus "$filename does not exist, take data for $corr first."
            return
        }
        lappend fileList $filename
    }
    
    if [catch {eval exec sddsxref $fileList -pipe=out \
                 -match=BPMName -take=*${plane}* \
                 | sddssortcolumn -pipe=in -sortList=BPMName,[join $corrList ,] \
                 ${plane}.meas.rm}  result] {
        return -code error "Error1 in combining measurement matrix: $result"
    }
    catch {exec sdds2csv -input ${rootname}${plane}.meas.rv -output ${plane}.meas.rm.csv}
    
}

set modelFile ""
proc CalculateMachineResponse {args} {
    set rootname0 ""
    set reprocess 0
    APSParseArguments {rootname0 reprocess}
    
    global plane outputDir CurrentAmp modelDir Sign index alpha freq rootname HModelDir VModelDir method selectDir
    if $reprocess {
       # cd $outputDir/$selectDir
        cd $outputDir
        #cd $selectDir
    } else {
        cd $outputDir
    }
    if ![string length $rootname0]  {
        set rootname0 $rootname
    }
    
    set corrList [list S27A:${plane}3 S27B:${plane}4 S28A:${plane}3 S28B:${plane}4]
    
    if ![file exist ${plane}corrnames.sdds] {
        if [catch { exec sddsmakedataset ${plane}corrnames.sdds -col=CorrectorNames,type=string -data=[join $corrList ,] } result] {
            return -code error "Error making corrector names file: $result"
        }
    }
    
    set fileList ""
    set findex [format %02d $index]
    set measList ""
    set  freq0 [expr int(ceil($freq))]
    set corrFile ""
    foreach corr $corrList  {
        set filename ${rootname0}-${corr}.mrm.R$findex
        set file ${rootname0}-${corr}.sdds.$findex
        if {$reprocess || ![file exist $filename] || ![file exist $file.proc]} {
            if [file exist $file] {
                switch $method {
                    NAFF {
                        if [catch {processDataWithNAFF -filename $file -corr $corr } result] {
                            return -code error "$result"
                        }
                    }
                    FFT {
                         if [catch {processDataWithFFT -filename $file -corr $corr } result] {
                            return -code error "$result"
                        }
                    }
                }
            } else {
                return -code error "No date found for $rootname0 $corr"
            }
        }
        lappend fileList $filename
        lappend correctors $corr
        lappend corrFile $file.proc
    }
    
    SetStatus "merging measurement matrix..."
    #corrector matrix
    if [catch {eval exec sddsxref $corrFile -take=S*${plane}* $rootname.$plane.corr -nowarnings } result] {
        return -code error "Error creating corrector drive matrix: $result"
    }
    
    if [catch {exec sddspseudoinverse $rootname.$plane.corr $rootname.$plane.corr.irm } result] {
        return -code error "Error1 computing inverse of corrector matrix."
    }
    
    if [catch {eval exec sddsxref $fileList -pipe=out \
                 -match=BPMName -take=*${plane}* \
                 | sddssortcolumn -pipe=in -sortList=BPMName,[join $correctors ,] \
                 ${rootname0}.${plane}.meas.R${findex} } result] {
        return -code error "Error2 in combining measurement matrix: $result"
    }
    SetStatus "Computing machine response matrix = MeasuredOrbit * Inverse of Corrector Matrix."
    if [catch {exec sddsmatrixmult ${rootname0}.${plane}.meas.R${findex} $rootname.$plane.corr.irm -pipe=out \
                 | sddsxref -pipe ${rootname0}.${plane}.meas.R${findex} -take=BPMName \
                 | sddsconvert -pipe=in  $rootname.$plane.machine.R${findex} \
                 -rename=col,Column000=[lindex $corrList 0],Column001=[lindex $corrList 1],Column002=[lindex $corrList 2],Column003=[lindex $corrList 3] \
             } result] {
        return -code error "Error3 in computing machine response matrix: $result"
    }
    #compute inverse
    if [catch {exec sddspseudoinverse -economy $rootname.$plane.machine.R${findex} $rootname.$plane.machine.R${findex}.irm -oldColumnNames=ControlName } result] {
        return -code error "Error4 in computing machine inverse matrix: $result"
    }
    SetStatus "done."
    return
    
    if [catch {exec sddspseudoinverse ${rootname0}.${plane}.meas.R${findex} ${rootname0}.${plane}.meas.R${findex}.irm } result] {
        return -code error "Error1a in computing inverse of measurement matrix: $result"
    }
    

    SetStatus "Computing model matrix = prevModel + alpha * delta..."
    #model matrix = previous model + alpha * measurement delta
   
    if {$index==0} {
        set filename [set ${plane}ModelDir].rm
        exec cp $modelDir/[set ${plane}ModelDir]/rm $filename
        set filename [set ${plane}ModelDir].irm
        set modelRM $filename
        catch {exec cp $modelDir/[set ${plane}ModelDir]/irm $filename}
        set model $filename
    } else {
        set prev [expr $index - 1]
        set fprev [format %02d $prev]
        if ![file exist ${rootname0}.$plane.model.R$fprev.irm] {
            return -code error "rootname0.$plane.model.R$fprev does not exist. you might need decreae the index or redo the measurement from beginning (index=0)."
        }
        
        set model ${rootname0}.$plane.model.R${fprev}.irm
    }
    
    # delta matrix  = -1 * MeasuredInverse * measuredMatrix * inverse of measuredMatrix;
        
    if [catch {exec sddsmatrixop $model -push=${rootname0}.${plane}.meas.R${findex} -mult -push=${rootname0}.${plane}.meas.R$findex.irm  -mult \
                 -scalarMult=-1.0 -pipe=out -columnNames=file=$modelDir/[set ${plane}ModelDir]/rm,column=BPMName \
                 | sddsxref -pipe=in $modelDir/[set ${plane}ModelDir]/irm -take=ControlName ${rootname0}.${plane}.delta.R$findex.irm } result] {
        return -code error "Error compute delta matrix: $result"
    }
    
    #new model inverse matrix = model inverse matrix + alpha * inverse of delta matrix   
    if [catch {exec sddsmatrixop $model -push=${rootname0}.${plane}.delta.R$findex.irm -scalarMult=$alpha -add \
                 -columnNames=file=$modelDir/[set ${plane}ModelDir]/rm,column=BPMName \
                 -pipe=out \
                 | sddsprocess -pipe "-redefine=par,alpha,$alpha" \
                 "-reprint=par,DeltaIRM,${rootname0}.${plane}.delta.R$findex.irm" \
                 | sddsxref -pipe=in $modelDir/[set ${plane}ModelDir]/irm -take=ControlName \
                 ${rootname0}.${plane}.model.R${findex}.irm } result] {
        return -code error "Error compute model inverse matrix: $result"
    }
    
    SetStatus "done."
    return
    
}

proc PlotData {args} {
    set type ""
    APSParseArguments {type}

    global outputDir plane CurrentAmp rootname index
    cd $outputDir
    set corrList [list S27A:${plane}3 S27B:${plane}4 S28A:${plane}3 S28B:${plane}4]
    switch $plane {
        H {
            set coord X
        }
        V {
            set coord Y
        }
    }
    foreach corr $corrList {
        set rootname1 ${rootname}-${corr}
        if ![file exist ${rootname1}.env.[format %02d $index]] {
            SetStatus "$rootname.env does not exist!"
            continue
        }
        switch $type {
            raw {
                exec sddsplot -title=$corr -sep=nameIndex -col=TimeMean,U*P*${coord}*LongErrorHistAMMean ${rootname1}.env.[format %02d $index] &
            }
            fft {
                exec sddsplot -title=$corr  -limits=xMinimum=40,xMaximum=50 -same=y -sep=nameIndex -col=f,FFT*${coord}* ${rootname1}.env.fft.[format %02d $index] &
            }
        }
    }
    
}

set Sign ""
set freqLoaded 0
proc ComputeFrequency {args} {
    set load 0
    APSParseArguments {load}
    global freq CurrentAmp outputDir Sign AFG freqLoaded
    set sampleRate [exec cavget -list=U:S27:OFB:DSP:LoopRateM ]
    
    set N 20480
    set time [expr $N * 1.0 / $sampleRate]
    set Np [expr int($freq * $time)]
   # puts $sampleRate
   # puts $Np
    set PI 3.141592653589793238462643
    set Np 40
    set freq [format %.3f [expr $Np * 1.0 /($N -1.0) * $sampleRate]]
   # set freq [format %.3f [expr 2.0 * $PI / 512.0]]
    if [catch {exec sddssequence -pipe=out -define=Index  -sequence=begin=0,end=[expr $N-1],interval=1,delta=1 \
                 | sddsprocess -pipe=in  $outputDir/perturbWaveform.sdds  \
                 "-reprint=par,Description,Perturbation Waveform at $freq Hz" \
                 "-redefine=col,time,Index $sampleRate /,units=s" \
                 "-reprint=par,WaveformPV,U:S27:OFB:${AFG}:WaveformC" \
                 "-redefine=col,Waveform,2.0 $PI * Index * 512 / sin $CurrentAmp *,units=Amps" } result] {
        return -code error "computefrequency0: $result"
    }
    exec sddsplot -grap=sym -col=time,Waveform  $outputDir/perturbWaveform.sdds -topline=@Description &
    if [catch {exec sddsfft $outputDir/perturbWaveform.sdds -pipe=out -col=Index,Waveform -full \
                 | sddsprocess -pipe  \
                 "-reprint=par,Description,Perturbation FFT Waveform at $freq Hz." \
                 "-process=FFTWaveform,max,FFTWaveformMax" \
                 "-process=FFTWaveform,max,FFTPeakFreq,functionof=f,position" \
                 | sddsprocess -pipe=in  $outputDir/perturbWaveform.fft "-redefine=col,ImagFFTWaveformAbs,ImagFFTWaveform abs" \
                 "-process=ImagFFTWaveformAbs,max,ImagFFTWaveformAbsMax" \
                 "-process=ImagFFTWaveformAbs,max,ImagAbsPeakFreq,function=f,position" \
                 "-process=ImagFFTWaveformAbs,max,ImagPeak,functionof=ImagFFTWaveform,position" \
             } result] {
        return -code error "computefrequency1: $result"
    }
    exec sddsplot $outputDir/perturbWaveform.fft  -col=f,FFT*  -topline=@Description \
      -par=FFTPeakFreq,FFTWaveformMax -grap=sym,sub=1,scale=2 -leg=spec=FFTPeakFreq -par=ImagAbsPeakFreq,ImagFFTWaveformAbsMax -grap=sym,sub=2,scale=2 -leg=spec=ImagAbsPeakFreq   &
    set imagPeak [exec sdds2stream -par=ImagPeak $outputDir/perturbWaveform.fft]
    if {$imagPeak<0} {
        set Sign -1
    } else {
        set Sign 1
    }
    if $load {
        if [catch {exec sddswput $outputDir/perturbWaveform.sdds } result] {
            return -code error "Error loading AFG waveform: $result"
        }
        set freqLoaded 1
    }
}

proc PlotIRM {args} {
    global outputDir
    cd $outputDir
    set files [glob -nocomplain irm*load]
    if ![llength $files] {
        SetStatus "No irm loading matrix found in $outputDir"
        return
    }
    eval exec sddsplot $files -leg=file -grap=sym,conn,vary=sub  \"-ylabel=matrix element(mm/A)\" -leg=file -col=Index,Waveform &
}

proc PlotBPMFFTRealVSindex {args} {
    global outputDir plane rootname
    cd $outputDir
    
    set corrList [list S27A:${plane}3 S27B:${plane}4 S28A:${plane}3 S28B:${plane}4]
    
    foreach corr $corrList {
        set files [glob -nocomplain ${rootname}-${corr}*.mrm.*]
        if ![llength $files] {
            continue
        }
        if [catch {eval exec sddscombine $files -pipe=out \
                     | sddstranspose -pipe \
                     | sddscombine -merge -pipe \
                     | sddsprocess -pipe=in ${corr}.bpm "-redefine=col,Index,i_row,type=long" } result] {
            return -code error $result
        }
        exec sddsplot ${corr}.bpm -topline=$corr -sep -grap=sym,vary=sub,conn,scale=2 -col=Index,S* &
    }
}


proc PlotDeltaMatrix {args} {
    global modelFile outputDir plane S27A3 S27B4 S28A3 S28B4 rootname
    cd $outputDir
    
    if ![string length $rootname] {
        GetRootname
    }
    set files [glob -nocomplain ${rootname}.${plane}.delta.R??.irm]
    
    if ![llength files] {
        return -code error "No delta matrix found for $plane."
    }
    set tmpRoot /tmp/[APSTmpString]
    set corrList [list S27A:${plane}3 S27B:${plane}4 S28A:${plane}3 S28B:${plane}4]
    
    foreach file $files {
        set index [scan $file ${rootname}.${plane}.delta.R%ld]
        if [catch {exec  sddsbreak $file -pipe=out -change=ControlName \
                     | sddsprocess -pipe -process=ControlName,first,Corrector \
                     "-redefine=col,Index,$index,type=long" \
                     | sddssplit -pipe=in -rootname=$tmpRoot.$index } result] {
            return -code error "PlotDelatMatrix2: $result"
        }
        lappend fileList([lindex $corrList 0]) ${tmpRoot}.${index}001.sdds
        lappend fileList([lindex $corrList 1]) ${tmpRoot}.${index}002.sdds
        lappend fileList([lindex $corrList 2]) ${tmpRoot}.${index}003.sdds
        lappend fileList([lindex $corrList 3]) ${tmpRoot}.${index}004.sdds
        
    }
    foreach corr $corrList {
        if [catch {eval exec sddscombine $fileList($corr) -merge ${corr}.delta -over } result] {
            return -code error "PlotDeltaMatrix3: $result"
        }
        eval file delete -force $fileList($corr)
        exec sddsplot -grap=sym,conn,vary=sub -leg -topline=$corr -col=Index,S* ${corr}.delta &
    }
}

proc PlotRawData {args} {
    global rootname index outputDir
    cd $outputDir
    set findex [format %02d $index]
    set files [glob -nocomplain ${rootname}-*.sdds.$findex]
    if ![llength $files] {
        SetStatus "No files found for $rootname with index=$index"
        return
    }
    if ![file exist perturbWaveform.sdds] {
        SetStatus "perturbWaveform.sdds does not exist!"
        return
    }
    
    foreach file $files {
        set corr [regsub ${rootname}- $file ""]
        set corr [regsub .sdds.$findex $corr ""]
        if [regexp H $corr] {
            set coord X
        } else {
            set coord Y
        }
        
        if ![file exist $file.drive] {
            exec sddsxref $file perturbWaveform.sdds  -take=Waveform -reuse -nowarnings -pipe=out  \
              | sddsconvert -pipe -retain=col,Time,Waveform,U*${coord}* \
              | sddsconvert -pipe=in $file.drive -rename=col,Waveform=$corr \
              -edit=col,U*,%/U://%/${coord}:OFB:LongErrorHistAM//
        }
       
        exec sddsplot -title=$corr -mode=y=normalize  -layout=2,5 -grap=line,vary -leg -split=page -sep=2 -groupby=request \
          -col=Time,$corr -col=Time,S27A:P0 $file.drive -endp \
          -col=Time,$corr -col=Time,S27A:P2 $file.drive -endp \
          -col=Time,$corr -col=Time,S27A:P3 $file.drive -endp \
          -col=Time,$corr -col=Time,S27A:P4 $file.drive -endp \
          -col=Time,$corr -col=Time,S27B:P4 $file.drive -endp \
          -col=Time,$corr -col=Time,S27B:P3 $file.drive -endp \
          -col=Time,$corr -col=Time,S27B:P2 $file.drive -endp \
          -col=Time,$corr -col=Time,S27B:P0 $file.drive -endp \
          -col=Time,$corr -col=Time,S28A:P0 $file.drive -endp \
          -col=Time,$corr -col=Time,S28A:P2 $file.drive -endp \
          -col=Time,$corr -col=Time,S28A:P3 $file.drive -endp \
          -col=Time,$corr -col=Time,S28A:P4 $file.drive -endp \
          -col=Time,$corr -col=Time,S28B:P4 $file.drive -endp \
          -col=Time,$corr -col=Time,S28B:P3 $file.drive -endp \
          -col=Time,$corr -col=Time,S28B:P2 $file.drive -endp \
          -col=Time,$corr -col=Time,S28B:P0 $file.drive -endp &
    }
}

proc PlotOpenLoopMatrix {args} {
    global method selectDir outputDir
    set mainDir  /home/helios/SR/daily/2017/09/28/2/S27IntegratedStudies/integral
    switch $selectDir {
        NAFF {
            set title "Naff (time)"
        }
        NAFFindex {
            set title "Naff (index)"
        }
        FFTamp {
            set title "fft magnitude"
        }
        FFTimag {
            set title "fft imaginary"
        }
    }
    #cd $mainDir/$selectDir
    cd $outputDir
    exec sddsplot -layout=2,2 -grap=sym,vary=sub,scale=3,conn -col=BPMName,S* \
      -split=page -group=nameIndex -sep=2 -leg=file,edit=%/.meas.R00//%/test//  h.2017-0619.00.rm testKp0Ki0.H.meas.R00 "-title=$title" &
}

proc PlotAllMatrix {args} {
    global selectDir outputDir
    set mainDir /home/helios/SR/daily/2017/09/28/2/S27IntegratedStudies/integral
    switch $selectDir {
        NAFF {
            set title "Naff (time)"
        }
        NAFFindex {
            set title "Naff (index)"
        }
        FFTimag {
            set title "fft imaginary"
        }
        FFTamp {
            set title "fft magnitude"
        }
    }
    #cd $mainDir/$selectDir
    cd $outputDir
    
    #exec  sddsplot -layout=2,2 -grap=sym,vary=sub,scale=3,conn -col=BPMName,S* -split=page \
    #  -group=nameIndex -sep=5 -leg=file,edit=%/.meas.R00//%/test//  \
     # h.2017-0619.00.rm testKp0Ki0.H.meas.R00 testKp0Ki0.025.H.meas.R00 testKp0Ki0.05.H.meas.R00 testKp0Ki0.1.H.meas.R00 "-title=$title" &
    #plot with normalize
    set corrList {S27A:H3 S27B:H4 S28A:H3 S28B:H4}
    set fileList {testKp0Ki0.H.meas.R00 testKp0Ki0.005.H.meas.R00 testKp0Ki0.01.H.meas.R00 testKp0Ki0.02.H.meas.R00 testKp0Ki0.05.H.meas.R00 testKp0Ki0.1.H.meas.R00 testKp0Ki0.2.H.meas.R00}
    set fileList1 ""
    foreach file $fileList {
        if [catch {exec sddsxref $file testKp0Ki0.H.meas.R00  -pipe=out -edit=col,S*,ai/Ref/ \
                     | sddsprocess -pipe "-proc=Ref*,max,%sMax" \
                     -proc=RefS27A:H3,max,S27A:H3Max,functionof=S27A:H3,pos \
                     -proc=RefS27B:H4,max,S27B:H4Max,functionof=S27B:H4,pos \
                     -proc=RefS28A:H3,max,S28A:H3Max,functionof=S28A:H3,pos \
                     -proc=RefS28B:H4,max,S28B:H4Max,functionof=S28B:H4,pos \
                     | sddsprocess -pipe "-redefine=col,%s,%s %sMax / Ref%sMax *,select=S*" \
                     | sddsprocess -pipe=in $file.norm "-redefine=col,Delta%s,%s Ref%s -,select=S*"  } result] {
            return -code error "Error1: $result"
        }
        lappend fileList1 $file.norm
    }
    eval exec  sddsplot -layout=2,2 -grap=sym,vary=sub,scale=3,conn -col=BPMName,S* -split=page \
      -group=nameIndex -sep=7 -leg=file,edit=%/.meas.R00//%/test//  \
      $fileList1  &
    eval exec  sddsplot -layout=2,2 -grap=sym,vary=sub,scale=3,conn -col=BPMName,Delta* -split=page \
      -group=nameIndex -sep=7 -leg=file,edit=%/.meas.R00//%/test//  \
      $fileList1  &
   
}

set indepCol Time
set window 0
set useImag 0
proc UpdateMethod {args} {
    global selectDir method window indepCol useImag
    set useImag 0
    switch $selectDir {
        NAFF {
            set method NAFF
            set window 0
            set indepCol Time
        }
        NAFFindex {
            set method NAFF
            set window 0
            set indepCol Time
        }
        FFTamp {
            set method FFT
            set window 1
            set indepCol Index
            set useImag 0
        }
        FFTimag {
            set method FFT
            set window 0
            set indepCol Index
            set useImag 1
        }
    }
}

set AFG AFG1
APSApplication . -name $appName -version $CVSRevisionAuthor \
    -overview { measure RTFB response matrix }

APSScrolledStatus .status -parent .userFrame -width 100 -textVariable status

APSLabeledEntry .dir -parent .userFrame -label "Output Directory:" -textVariable outputDir -width 90
APSButton .daily -parent .userFrame.dir -text "daily" -size small -command "set outputDir [APSGoToDailyDirectory -subdirectory S27IntegratedStudies]"
APSLabeledEntry .model -parent .userFrame -label "Modal matrix dir:" -textVariable modelDir -width 90
APSFrameGrid .grid -parent .userFrame -xList {x1 x2} -label  "Data Collection Parameters"
set w1 .userFrame.grid.x1
set w2 .userFrame.grid.x2
APSLabeledEntry .hmodel -parent $w1 -label "H model dir:" -width 25 -textVariable HModelDir
APSLabeledEntry .vmodel -parent $w2 -label "V model dir:" -width 25 -textVariable VModelDir
APSLabeledEntry .interval -parent $w1 -label "Interval (seconds):" -width 25 -textVariable interval
APSLabeledEntry .steps -parent $w2 -label "Steps:" -width 25 -textVariable steps
APSLabeledEntry .current -parent $w1 -label "Corrector current(A)" -width 25 -textVariable CurrentAmp
APSLabeledEntry .alpha -parent $w2 -label "Alpha" -width 25 -textVariable alpha
APSLabeledEntry .freq -parent $w1 -label "Perturb frequency (Hz):" -width 25 -textVariable freq
APSButton .compute -parent $w1.freq -text "Update" -size small -command "ComputeFrequency"
APSLabeledEntry .index -parent $w2 -label "Index of delta matrix" -width 25 -textVariable index -contextHelp "give the index of response matrix measurement." 
APSRadioButtonFrame .plane -parent $w1 -label "Plane:" -buttonList {H V} -valueList {H V} -variable plane -orientation horizontal
set rootname testKp0Ki0
APSLabeledEntry .root -parent $w1 -label "Rootname:" -textVariable rootname -width 25
APSButton .get -parent $w1.root -packOption "-side right" -text "update" -size small -command "set rootname [clock format [clock seconds] -format %Y-%m%d:%H%M%S]"
APSButton .f -parent $w1.root -packOption "-side right" -text "F" -size small -command "GetRootname"

set method FFT
APSRadioButtonFrame .method -parent $w2 -label "Processing method:" -variable method -buttonList {FFT NAFF} -valueList {FFT NAFF} \
  -orientation horizontal

APSRadioButtonFrame .afg -parent $w2 -label "AFG waveform:" -buttonList {AFG1 AFG2 AFG3 AFG4} -valueList {AFG1 AFG2 AFG3 AFG4} -variable AFG -orientation horizontal
#set S27A3 1
#set S27B4 1
#set S28A3 1
#set S28B4 1
#APSCheckButtonFrame .corr -parent .userFrame -label "Select correctors:" -buttonList {S27A:\[HV\]3 S27B:\[HV\]4 S28A:\[HV\]3 S28B:\[HV\]4} \
#  -variableList {S27A3 S27B4 S28A3 S28B4} -allNone 1 -orientation horizontal

APSFrame .f1 -parent .userFrame 
APSFrame .f2 -parent .userFrame
.userFrame.f1.frame configure -bd 0
.userFrame.f2.frame configure -bd 0
set w1 .userFrame.f1.frame
set w2 .userFrame.f2.frame
#APSButton .collect -parent .userFrame -text "Collect Data" -command "CollectData"
#APSButton .compute -parent .userFrame -text "Compute Delta" -command "CalculateRespDelta"
APSButton .start -parent $w1 -text "Start RM delta measurement" -command "Start"
#APSButton .collect -parent .userFrame -text "Collect Data" -command "CollectData"
APSButton .compute -parent $w1 -text "Compute Machine Response" -command "CalculateMachineResponse"
APSButton .load -parent $w1 -text "Load IRM" -command "LoadIRM1 -plot 1"

APSButton .plot1 -parent $w1  -text "Plot IRM" -command "PlotIRM"
APSButton .plot2 -parent $w1 -text "Plot BPM FFT_Real vs Index" -command "PlotBPMFFTRealVSindex"
#APSButton .plot3 -parent $w2 -text "Plot Delta Norm" -command "PlotNorm"
#APSButton .plot4 -parent $w2 -text "Plot Delta Matrix" -command "PlotDeltaMatrix"
APSButton .plot5 -parent $w2 -text "Plot Raw Data" -command "PlotRawData"

set selectDir ""
#APSRadioButtonFrame .dir1 -parent .userFrame -label "Select directory for plot" \
#  -buttonList {NAFF NAFFindex FFTamp FFTimag} -valueList {NAFF NAFFindex FFTamp FFTimag} \
 # -variable selectDir -commandList {UpdateMethod UpdateMethod UpdateMethod UpdateMethod}

APSButton .proca -parent .userFrame -text "Process Data" -command "CalculateMachineResponse -reprocess 1"
APSButton .plot6 -parent .userFrame -text "Plot Open Loop Matrix" -command "PlotOpenLoopMatrix"
APSButton .plotall -parent .userFrame -text "Plot All Matrix"  -command "PlotAllMatrix"
