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

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

set CVSRevisionAuthor "\$Revision: 1.0 $ \$Author: shang $"

proc SetStatus {text} {
    global status
    set status "[exec date]: $text"
    update
}

proc TakeWaveformData {args} {
    global outputDir freq IPaddress description DG1delay
    
   
    if [catch {exec cavget -list=Popt:DG1:dDelaySetAO -pend=10 } delay0] {
	return -code error "Error reading delay: $delay0"
    }
    SetStatus "The par optics timing is $delay0 now."
    if {0} {
    switch $freq {
	2Hz {
	    #2Hz (or pick a value synchronized with video):
	    set delay  0.457
	}
	1Hz {
	#1Hz (end of cycle, we no longer use the video):
	    set delay  0.95
	}
    }
    }
    SetStatus "set Popt:DG1:dDelaySetAO to $DG1delay..."
    if [catch {exec cavput -list=Popt:DG1:dDelaySetAO=$DG1delay -pend=10} result] {
	return -code error "Error setting Popt:DG1:dDelaySetAO : $result"
    }
    after 100
    if [catch {exec cavget -list=Popt:DG1:dDelaySetAO -pend=10 } delay1] {
	return -code error "Error reading delay: $delay0"
    }
    SetStatus "The par optics timing now is $delay1 now."
    SetStatus "Acquire data..."
    set filename PARBDM-[clock format [clock seconds] -format %Y-%m%d:%H%M%S].sdds
    if [catch {exec collectParBunchLengthScopeData -instName $IPaddress  -filename $outputDir/$filename \
		   -description "$description"} result] {
	return -code error "Error collecting scope waveform: $result"
    }
    SetStatus "data collection done. processing data..."
    if [catch {ProcessData1 -filename $outputDir/$filename} result] {
	return -code error "Error processing data: $result"
    }
    SetStatus "done."
}

proc ScopeViewer {args} {
    global IPaddress env
    APSInfoWindow .info -name "check trigger" -modal 1\
	-infoMessage "On scope, middle black box immediately below scope waveform should be 0.0 s" 
    puts "[exec which vnceviewer]"
    
    exec vnceviewer -PasswordFile /home/helios/[string toupper $env(USER)]/.vnc/passwords/scope agilabscope &
}

proc ProcessData1 {args} {
    set filename ""
    set plot 0
    APSParseArguments {filename plot}
    
    global deconvFile noiseLevel removePages
    SetStatus "processing $filename ..."
    if [catch {exec sddsprocess $filename -pipe=out \
		   "-redefine=col,Index,i_row,type=long" \
		   | sddsprocess -pipe \
		   "-def=col,Signal,Channel2 chs,type=double,units=V" \
		   "-def=col,tns,Index 5e-11 * 1e9 *,type=double,units=ns" \
		   "-def=para,bunchPeriod,30.667 c_mks /" \
		   "-def=col,bunchNo,tns 1e-9 * bunchPeriod /,type=double" \
		   | sddsprocess -pipe  "-def=par,TT,30.667 c_mks / 1e9 *,type=double,units=ns" \
		   -proc=Signal,maximum,maxSig,functionOf=tns,upperLimit=@TT \
		   -proc=Signal,maximum,maxtns,functionOf=tns,lowerLimit=0,position,upperLimit=@TT \
		   "-def=par,tnsStart,maxtns 3 -,type=double,units=ns" \
		   "-def=par,tnsStop,TT 127 * tnsStart + 12.05 +,type=double,units=ns" \
		   | tee $filename.proc \
		   | sddsprocess -pipe=in $filename.proc1  \
		   "-redef=col,tns,tns tnsStart -,type=double,units=ns" \
		   "-def=col,bunchNoShift,tns 1e-9 * bunchPeriod / int,type=long" } result] {
	return -code error "Error processing data1: $result"
    }
    SetStatus "data processing2..."
    if [catch {exec sddsbreak $filename.proc1 -changeof=bunchNoShift -pipe=out \
		   | sddsprocess -pipe=in $filename.proc.break.clip \
		   -clip=240,0,invert \
		   -proc=tns,first,First \
		   -proc=tns,last,Last \
		   "-def=par,meanGuess,First 2 +,type=double,units=ns" \
		   "-def=par,endRange,meanGuess 2 +,type=double,units=ns" } result] {
	return -code error "Error processing data2: $result"
    }
    set rows [exec sdds2stream -rows=bar $deconvFile]
    SetStatus "Remove noise data..."
    if [catch {exec sddsprocess  $filename.proc1 -pipe=out -proc=Signal,max,MaxSignal \
		   | sdds2stream -pipe=in -par=MaxSignal } maxSig] {
	return -code error "Error getting the max signal: $maxSig"
    }
    
    if [catch {exec sddsprocess $filename.proc.break.clip -pipe=out -proc=Signal,max,MaxSignal \
		   "-redefine=par,Rows,n_rows,type=long" "-redefine=par,Page,i_page,type=long" \
		   | sddsprocess -pipe -filter=par,Rows,$rows,$rows \
		   | sddsprocess -pipe "-redefine=par,MaxSignal,MaxSignal $maxSig /" \
		   | sddsprocess -pipe=in $filename.proc.break.clip.proc -filter=par,MaxSignal,$noiseLevel,1.1 } result] {
	return -code error "Error remove noise data: $result"
    }
    set removePages [string trim $removePages] 
    if [string length $removePages] {
	set opt ""
	foreach page $removePages {
	    lappend opt "-filter=par,Page,$page,$page,!"
	}
	if [catch {eval exec sddsprocess $filename.proc.break.clip.proc -pipe=out \
		       | sddsprocess -pipe=in $filename.proc.break.clip.proc1 $opt } result] {
	    return -code error "Error remove pages: $result"
	}
	exec mv $filename.proc.break.clip.proc1 $filename.proc.break.clip.proc
    }
    SetStatus "deconvolution..."
    if [catch {exec sddsconvolve $filename.proc.break.clip.proc $deconvFile  \
		   $filename.deConv -signalColumns=tns,Signal \
		   -responseColumns=t,Spz -outputColumns=tc,SigConvolve -deconvolve } result] {
	return -code error "Error deconvoling data: $result"
    }
    SetStatus "smoothing and fitting..."
    if [catch {exec sddssmooth $filename.deConv -passes=2 \
		   -column=SigConvolve -pip=out \
		   | sddsprocess -pipe \
		   "-define=col,tb,tc First -,type=double,units=ns" \
		   -proc=SigConvolve,fwhm,FWHM,functionOf=tb,lowerLimit=0,upperLimit=10 \
		   | sddsgfit -pipe -fullOutput \
		   -guesses=height=0.5,mean=2.00,sigma=0.5,baseline=0.00 -fitrange=0.0,10.0 \
		   -limits=evaluations=20,passes=10 -col=tb,SigConvolve \
		   | sddsprocess -pipe \
		   "-define=par,kQ,gfitHeight gfitSigma *,type=double" \
		   | tee $filename.proc.gfit \
		   | sddsconvert -pipe -retain=col,tb,SigConvolve \
		   | sddsenvelope -pipe -mean=SigConvolve -copy=tb \
		   | sddsconvert -pipe -edit=col,*,%/Mean// \
		   | sddsgfit -pipe  -guesses=height=0.5,mean=2.05,sigma=0.5,baseline=0.00 -fitrange=0.05,10.05 \
		   -limits=evaluations=20,passes=10 -col=tb,SigConvolve -fullOutput \
		   | sddsprocess -pipe=in $filename.proc.ave.gfit \
		   "-redefine=par,kQ,gfitHeight gfitSigma *,type=double" \
	       } result] {
	return -code error "Error processing data3: $result"
    }
    if [catch {exec sddscollapse $filename.proc.gfit -pipe=out \
		   | sddsprocess -pipe=in $filename.proc.gfit.stats \
		   -proc=gfitBaseline,average,aveBL \
		   -proc=gfitBaseline,standarddeviation,stdevBL \
		   -proc=gfitHeight,average,aveA \
		   -proc=gfitHeight,standarddeviation,stdevA \
		   -proc=gfitMean,average,aveMean \
		   -proc=gfitMean,standarddeviation,stdevMean \
		   -proc=gfitSigma,average,aveSig \
		   -proc=gfitSigma,standarddeviation,stdevSig \
		   -proc=FWHM,average,aveFWHM \
		   -proc=FWHM,average,FWHM \
		   -proc=FWHM,standarddeviation,stdevFWHM \
		   -proc=kQ,average,avekQ \
		   -proc=kQ,average,kQ \
		   -proc=kQ,standarddeviation,stdevkQ } result] {
	return -code error "Error processing stats: $result"
    }
    if [catch {exec sddsxref $filename.proc.ave.gfit $filename.proc.gfit.stats $filename.ave.gfit \
		   -leave=* -transfer=par,FWHM,kQ,aveSig } result] {
	return -code error "Error transferring FWHM, kQ parameters: $result"
    }
    set bunchLen [exec sdds2stream -par=aveSig $filename.ave.gfit]
    set bunchLen [format %.3f [expr $bunchLen * 1000.0]]
    SetStatus "The average bunch length is $bunchLen ps."
    SetStatus "done."
    if $plot {
	PlotData1 -filename $filename 
    } 
}

proc PlotData1 {args} {
    set filename ""
    set rawData 0
    APSParseArguments {filename rawData}
    
    global plotNoAve
    if $rawData {
	exec sddsplot -col=Channel2 $filename &
	return
    }
    if ![file exist $filename.ave.gfit] {
	if [catch {ProcessData1 -filename $filename } result] {
	    return -code error "Error processing data: $result"
	}
    }
    if $plotNoAve {
	    exec sddsplot $filename.proc.gfit -split=page -sep=2 -group=page -thick=2 -leg \
		"-topline=Plot of each turn" \
		-grap=sym,vary=sub,fill,scale=2  \
		-col=tb,SigConvolve -grap=sym,scale=2,fill,sub=1 \
		-col=tb,SigConvolveFit -grap=line,thick=2  \
		"-string=A = ,pCoord=0.46,qCoord=0.93,scale=1.1" \
		-string=@gfitHeight,pCoord=0.53,qCoord=0.93,scale=1.1 \
		-string=@gfitMean,pCoord=0.54,qCoord=0.83,scale=1.1 \
		"-string=t\$bc0\$n = ,pCoord=0.46,qCoord=0.83,scale=1.1" \
		"-string=ns,pCoord=0.83,qCoord=0.83,scale=1.1" \
		"-string=bl = ,pCoord=0.46,qCoord=0.73,scale=1.1" \
		-string=@gfitBaseline,pCoord=0.54,qCoord=0.73,scale=1.1 \
		"-string=t\$bFWHM\$n = ,pCoord=0.46,qCoord=0.63,scale=1.1" \
		-string=@FWHM,pCoord=0.57,qCoord=0.63,scale=1.1 \
		"-string=ns,pCoord=0.86,qCoord=0.63,scale=1.1" \
		"-string=kQ = ,pCoord=0.46,qCoord=0.53,scale=1.1" \
		-string=@kQ,pCoord=0.54,qCoord=0.53,scale=1.1 \
		-string=@gfitSigma,pCoord=0.54,qCoord=0.43,scale=1.1 \
		"-string=\$gs\$r\$bt\$n = ,pCoord=0.46,qCoord=0.43,scale=1.1" \
		"-string=ns,pCoord=0.83,qCoord=0.43,scale=1.1" &
    }
   
    exec sddsplot $filename.ave.gfit -split=page -sep=2 -group=page -thick=2  \
	"-title=[file root [file tail $filename]]" \
	-grap=sym,vary=sub,fill,scale=2  \
	-col=tb,SigConvolve -leg=spec=Average_data -grap=sym,scale=2,fill,sub=1 \
	-col=tb,SigConvolveFit -leg=spec=Fit  -grap=line,thick=2  \
	"-string=A = ,pCoord=0.46,qCoord=0.93,scale=1.1" \
	-string=@gfitHeight,pCoord=0.53,qCoord=0.93,scale=1.1 \
	-string=@gfitMean,pCoord=0.54,qCoord=0.83,scale=1.1 \
	"-string=t\$bc0\$n = ,pCoord=0.46,qCoord=0.83,scale=1.1" \
	"-string=ns,pCoord=0.83,qCoord=0.83,scale=1.1" \
	"-string=bl = ,pCoord=0.46,qCoord=0.73,scale=1.1" \
	-string=@gfitBaseline,pCoord=0.54,qCoord=0.73,scale=1.1 \
	"-string=t\$bFWHM\$n = ,pCoord=0.46,qCoord=0.63,scale=1.1" \
	-string=@FWHM,pCoord=0.57,qCoord=0.63,scale=1.1 \
	"-string=ns,pCoord=0.86,qCoord=0.63,scale=1.1" \
	"-string=kQ = ,pCoord=0.46,qCoord=0.53,scale=1.1" \
	-string=@kQ,pCoord=0.54,qCoord=0.53,scale=1.1 \
	-string=@gfitSigma,pCoord=0.54,qCoord=0.43,scale=1.1 \
	    "-string=\$gs\$r\$bt\$n = ,pCoord=0.46,qCoord=0.43,scale=1.1" \
	"-string=ns,pCoord=0.83,qCoord=0.43,scale=1.1" &
    
    
    exec sddsplot $filename.ave.gfit -split=page -sep=2 -group=page -thick=2  \
	-grap=sym,vary=sub,fill,scale=2  \
	-col=tb,SigConvolve -leg=spec=[file root [file  tail $filename]] -grap=sym,scale=2,fill,sub=1 \
	-col=tb,SigConvolveFit -leg=spec=Fit  -grap=line,thick=2  \
	"-string=A = ,pCoord=0.46,qCoord=0.93,scale=1.1" \
	-string=@gfitHeight,pCoord=0.53,qCoord=0.93,scale=1.1 \
	-string=@gfitMean,pCoord=0.54,qCoord=0.83,scale=1.1 \
	"-string=t\$bc0\$n = ,pCoord=0.46,qCoord=0.83,scale=1.1" \
	"-string=ns,pCoord=0.83,qCoord=0.83,scale=1.1" \
	"-string=bl = ,pCoord=0.46,qCoord=0.73,scale=1.1" \
	-string=@gfitBaseline,pCoord=0.54,qCoord=0.73,scale=1.1 \
	"-string=t\$bFWHM\$n = ,pCoord=0.46,qCoord=0.63,scale=1.1" \
	-string=@FWHM,pCoord=0.57,qCoord=0.63,scale=1.1 \
	"-string=ns,pCoord=0.86,qCoord=0.63,scale=1.1" \
	"-string=kQ = ,pCoord=0.46,qCoord=0.53,scale=1.1" \
	    -string=@kQ,pCoord=0.54,qCoord=0.53,scale=1.1 \
	-string=@gfitSigma,pCoord=0.54,qCoord=0.43,scale=1.1 \
	"-string=\$gs\$r\$bt\$n = ,pCoord=0.46,qCoord=0.43,scale=1.1" \
	"-string=ns,pCoord=0.83,qCoord=0.43,scale=1.1" \
	-dev=lpng -out=$filename.ave.gift.png  
}

proc ProcessData {args} {
    global outputDir SelectFile
    cd $outputDir
   # set files [glob -nocomplain PARBDM*.sdds]
    set files [lsort -decreasing [glob -nocomplain *.sdds]]
    
    if ![llength $files] {
	SetStatus "No data found."
	return
    }
    set SelectFile ""
    
    APSScrolledListWindow .proc1 -name "Select File" -label "Select File"\
      -itemList $files -selectionVar SelectFile 

    tkwait variable SelectFile
    if ![string length $SelectFile] {
	SetStatus "no file chosen."
	return
    }
    foreach file $SelectFile {
	if [catch {ProcessData1 -filename $file -plot 1} result] {
	    return -code error "Error processing $file: $result"
	}
    }
}

proc PlotData {args} {
    set rawData 0
    APSParseArguments {rawData}
    global outputDir SelectFile
    cd $outputDir
    set files [lsort -decreasing [glob -nocomplain *.sdds]]
    if ![llength $files] {
	SetStatus "No data found."
	return
    }
    set SelectFile ""
    APSScrolledListWindow .plot1 -name "Select File" -label "Select File" \
	-itemList $files -selectionVar SelectFile 
    
    tkwait variable SelectFile
    if ![string length $SelectFile] {
	SetStatus "no file chosen."
	return
    }
    foreach file $SelectFile {
	PlotData1 -filename $file -rawData $rawData
    }
}

proc SaveScopeSetup {args} {
    global IPaddress scopeSetupDesc scopeArchiveDir
    
    if ![string length $scopeSetupDesc] {
	APSInfoWindow "Please provide the scope setup description!" -modal 1
	return
    }
    set rootname [clock format [clock seconds] -format %Y%m%d-%H%M%S]
    set timeStamp [exec date]
    
    SetStatus "Saving scope settings..."
    
    if [catch {exec sendHP9000ScopeCommand -instName $IPaddress \
                 -command "DISK:SAVE:SETup \'H:\\agilent-7ec1\\setup\\$rootname.set\'" } result] {
        return -code error "Error save scope setup: $result"
    }
    
    if [catch {exec sddsmakedataset $scopeArchiveDir/$rootname.log \
		   -col=Filename,type=string -data=$rootname.set \
		   -col=TimeStamp,type=string -data="$timeStamp" \
		   -col=Description,type=string -data=[APSMakeSafeQualifierString $scopeSetupDesc] } result] {
	return -code error "Error creating scope setup log file: $result"
    }
    exec chmod u+w $scopeArchiveDir/$rootname.set
    exec chmod u+w $scopeArchiveDir/$rootname.log
    cd $oldDir
    SetStatus "done."
}

proc RestoreScopeSettings {args} {
    global IPaddress scopeSetupDesc scopeArchiveDir
    set oldDir [pwd]
    cd $scopeArchiveDir
    set files [glob -nocomplain *.log]
    if ![llength $files] {
	SetStatus "No setup files found."
	return
    }
    set tmpFile /tmp/[APSTmpString]
    APSAddToTmpFileList -ID PDM -fileList $tmpFile
    if [catch {eval exec sddscombine $files -merge -pipe=out \
		   | sddssort -pipe=in $tmpFile -col=Filename,decr } result] {
	return -code error "Error searching for setup files: $result"
    }
    cd $oldDir
    APSMakeSDDSListbox $tmpFile .restore -title "Scope restore choices" \
	-page 0 -labelmaker MakeLBoxTextLine  -packOption "-side top -expand true -fill y" \
        -callback RestoreScopeSetup  \
        TimeStamp Description Filename
    exec rm $tmpFile
}

proc MakeLBoxTextLine {data width} {
    set timestamp [lindex $data 0]
    set wt [lindex $width 0]
    set description [lindex $data 1]
    set wd [lindex $width 1]
    set filename [lindex $data 2]
    set wf [lindex $width 2]
    set rootname [file rootname $filename]
    if [file exists $rootname.preferred] {
        set suffix " *"
    } else {
        set suffix "  "
    }
  
    set sform [format "%%%lds    %%%lds$suffix" $wt $wd]
    return [format $sform $timestamp $description]
}

proc RestoreScopeSetup {TimeStamp Description Filename} {
    global IPaddress scopeSetupDesc scopeArchiveDir
    set scopeSetupDesc $Description
    set filename $scopeArchiveDir/$Filename
    SetStatus "restore scope settings ($Description)..."
    if [catch {exec sendHP9000ScopeCommand -instName 164.54.3.155 \
                 -command ":DISK:LOAD \'H:\\agilent-7ec1\\setup\\$Filename\'" } result] {
        return -code error "Error load scope setup: $result"
    }
    SetStatus "done."
}

set scopeArchiveDir /home/helios/oagData/par/scope/BDM
set scopeArchiveDir /net/oxygen/pcfiles/pc/scopeusr_share/agilent-7ec1/setup
set outputDir [APSGoToDailyDirectory -subdirectory parBDM]
#set outputDir .
#set outputDir 
set freq 1Hz
set IPaddress 10.6.56.37
set plot 0
set description ""
set scopeSetupDesc ""
set deconvFile /home/helios5/PAR/diagnostics/160404_185818.155A.csv.sdds.ns.z.68_80ns.comb.128T

APSApplication . -name PARBunchDurationMonitor -version $CVSRevisionAuthor \
  -overview {measurement par tune with booster VSA instrument.}

set status Working...
APSScrolledStatus .status -parent .userFrame -textVariable status \
        -width 80 -height 6

set wList [APSTabFrame .tab -parent .userFrame -labelList "Measurement ScopeSetup" -width 900 -height 300]
set w1 [lindex $wList 0]
set w2 [lindex $wList 1]
APSLabeledEntry .dir -parent $w1 -label "Output directory:" -width 85 -textVariable outputDir
APSButton .daily -parent $w1.dir -text "daily" -command "set outputDir [APSGoToDailyDirectory -subdirectory parBDM]"
APSLabeledEntry .desc -parent $w1 -label "Description" -textVariable description -width 85
APSLabeledEntry .decon -parent $w1 -label "Deconvolution file:" -width 85 -textVariable deconvFile -fileSelectButton 1 \
    -buttonsOnLeft 1
APSLabeledEntry .ip -parent $w1 -label "Scope IP address:" -width 40 -textVariable IPaddress

set DG1delay 0.95
APSRadioButtonFrame .video -parent $w1 -label "1Hz/2Hz?" -buttonList {1Hz 2Hz} -valueList {1Hz 2Hz} \
    -orientation horizontal -variable freq -commandList {"set DG1delay 0.95" "set DG1delay 0.457"}
APSLabeledEntry .dg1delay -parent $w1.video -label "   DG1 delay:" -textVariable DG1delay -width 40
set noiseLevel 0.5
APSLabeledEntry .moise -parent $w1 -label "Noise filter (relative to maximum, should be <1.0):" -width 30 -textVariable noiseLevel
set removePages ""
APSLabeledEntry .pages -parent $w1 -label "Page to be removed (separate by space):" -width 50 -textVariable removePages
set plotNoAve 1
APSRadioButtonFrame .pl -parent $w1 -label "Plot Each Turn?" -buttonList {Yes No} -valueList {1 0} \
    -orientation horizontal -variable plotNoAve

APSFrame .f2 -parent $w1
set w0 $w1.f2.frame
#exec vnceviewer -PasswordFile ~/.vnc/passwords/scope agilabscope &
APSButton .scope -parent $w0 -text "Scope VNC" -command "ScopeViewer"
APSButton .take -parent $w0  -text "Measure" -command "TakeWaveformData"
APSButton .process -parent $w0 -text "Process" -command "ProcessData"
APSButton .plot -parent $w0  -text "Plot" -command "PlotData"
APSButton .plot1 -parent $w0 -text "Plot Raw Data" -command "PlotData -rawData 1"

#APSFrame .f1 -parent .userFrame -label "Scope Setup"
#set w .userFrame.f1.frame
APSLabeledEntry .desc -parent $w2 -label "Scope Setup description:" -textVariable scopeSetupDesc -width 85
APSButton .save -parent $w2 -text "Save Scope Setup" -command "SaveScopeSetup"
APSButton .restore -parent $w2 -text "Restore Scope Setup" -command "RestoreScopeSettings"

#scope net work dir
#/net/oxygen/pcfiles/pc/scopeusr_share/agilent-7ec1/setup
#user APS\scopeuser   password tek#scp9

#:DISK:LOAD 
#restore setup
#sendHP9000ScopeCommand -instName 164.54.3.155 -command ":DISK:LOAD 'H:\agilent-7ec1\setup\PAR-BDMSetupTest.set'"

#save setup
#sendHP9000ScopeCommand -instName 164.54.3.155 -command "DISK:SAVE:SETup 'H:\agilent-7ec1\setup\test.set'"

