#!/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)]
APSDebugPath

set CVSRevisionAuthor "\$Revision: 1.20 $ \$Author: sajaev $"

APSApplication . -name "SRsurveyData" -version $CVSRevisionAuthor \
  -overview "SRSurveyData plots present and past SR magnet alignment dataplot."

set SRPlotSurveyStatus "Initializing ..."
APSScrolledStatus .status -parent .userFrame -width 90 \
  -textVariable SRPlotSurveyStatus 

proc SetSRPlotSurveyStatus {text} {
    global SRPlotTrajectoryStatus
    set SRPlotTrajectoryStatus $text
    update
    bell
}

proc FindDataSets {} {
    global dataDir outputDir
    cd $dataDir
    set dirList [lsort [glob 199? 199?.* 20?? 20??.*]]
    foreach dir $dirList {
        if [file isdirectory $dir] {
            lappend returnList $dir
        }
    }
    cd $outputDir
    return $returnList
}

proc MakeInputFrame {widget args} {
    global realMeasurementList
    APSStrictParseArguments {parent}
    
    set w $parent$widget.frame
    APSFrame $widget -parent $parent -label "Input parameters"

    APSLabeledEntry .first -parent $w \
      -label "First sector:" -textVariable first \
      -contextHelp "Enter the first sector to plot. If larger than the last sector, will wrap around. Wrap around does not work for \"smoothed\" plotting." -width 10
    APSLabeledEntry .last -parent $w \
      -label "Last sector:" -textVariable last \
      -contextHelp "Enter the last sector to plot. If smaller than the first sector, will wrap around. Wrap around does not work for \"smoothed\" plotting." -width 10
    global dataSetList
    set dataSetList [FindDataSets]
    set buttonList ""
    foreach dataSet $dataSetList {
	global $dataSet
	if {[lsearch -exact $realMeasurementList $dataSet] != -1} {lappend buttonList ${dataSet}*} else {lappend buttonList $dataSet}
    }
    APSCheckButtonFrame .dataChoiceFrame -parent $w \
      -orientation  vertical -limitPerRow 4 \
      -packOption {-side top -fill x} \
      -label "Data Sets" \
      -buttonList $buttonList \
      -variableList $dataSetList \
      -contextHelp "List of available data sets. \"*\" denotes full surveys. Some plot commands allow for multiple selections, others ignore and use only first data set."
    return
}

proc MakePlotInputFrame {widget args} {
    global sectorFitRange polynom outputRoot
    APSStrictParseArguments {parent}
    
    set w $parent$widget.frame
    APSFrame $widget -parent $parent -label "Plot options"

    APSLabeledEntry .sectorFitRange -parent $w \
      -label "Sector fit range (odd number):" -textVariable sectorFitRange \
      -contextHelp "For smoothing only: For each sector, the fit will be done over this number of sectors with the main sector in the middle." -width 55
    APSLabeledEntry .polynom -parent $w \
      -label "Number of polynomial terms in the fit:" -textVariable polynom \
      -contextHelp "For smoothing only: The fit will be done using sddsmpfit with this number of terms. Odd number is preferred." -width 55
    APSLabeledEntry .nPrintout -parent $w \
      -label "Number of girders to printout:" -textVariable nPrintout \
      -contextHelp "For smoothing only: This number of worst displaced girders will be printed out." -width 55
    APSLabeledEntry .outputRoot -parent $w \
      -label "Output rootname:" -textVariable outputRoot \
      -contextHelp "If not empty, will be used for plot file names instead of APSTmpString. Useful for manual comparison plots of several data sets." -width 55
    APSRadioButtonFrame .analysis  -parent  $w \
      -label "Statistics analysis" -orientation horizontal -limitPerRow 2 \
      -variable analysis \
      -buttonList {"StDev" "Max"} \
      -valueList {stand maximum} \
      -contextHelp "Girder displacement relative to the smooth line will be analyzed using this analysis."
    APSRadioButtonFrame .output  -parent  $w \
      -label "Plot output" -orientation horizontal -limitPerRow 3 \
      -variable makePng \
      -buttonList {"No output" "png" "ceps"} \
      -valueList {0 1 2} \
      -contextHelp "Image files with plots will be created and saved in /tmp directory."
    return
}

proc GetChosenDataSets {args} {
    global dataSetList
    set outputList ""
    foreach dataSet $dataSetList {
	global $dataSet
	if [set $dataSet] {lappend outputList $dataSet}
    }
    return $outputList
}

proc MakePlotCommandFrame {widget args} {
    global sectorFitRange polynom outputRoot
    APSStrictParseArguments {parent}
    
    set w $parent$widget.frame
    APSFrame $widget -parent $parent -label "Plot commands"
    
    APSButton .plot -parent $w \
	-text "Plot"  \
	-packOption "-side left" \
	-command {
	    cd $dataDir
	    set dataSetChosen [GetChosenDataSets]
	    if [catch {plotSurveyData -first $first -last $last -dataSetChosen $dataSetChosen -makePng $makePng \
			   -outputRoot $outputRoot} result] {
		APSSetVarAndUpdate SRPlotSurveyStatus "plotSurveyData: $result"
	    }
	    cd $outputDir
	} \
	-contextHelp "Plot data for selected sectors. If more than one set chosen, will plot differences as well."
    APSButton .plot1 -parent $w \
	-text "Plot smoothed"  \
	-packOption "-side left" \
	-command {
	    cd $dataDir
	    set dataSetChosen [GetChosenDataSets]
	    if {[llength $dataSetChosen] > 1} {set SRPlotSurveyStatus "Warning: Only first data set will be used in plotting."}
	    if [catch {plotSmoothedSurveyData -first $first -last $last -dataSet [lindex $dataSetChosen 0] \
			   -sectorFitRange $sectorFitRange -polynom $polynom -makePng $makePng \
			   -analysis $analysis -nPrintout $nPrintout -outputRoot $outputRoot} result] {
		APSSetVarAndUpdate SRPlotSurveyStatus "plotSmoothedSurveyData: $result"
	    }
	    cd $outputDir
	} \
	-contextHelp "Plots smoothed data and differences."
    APSButton .plot2 -parent $w \
	-text "Plot with BPM setpoints"  \
	-packOption "-side left" \
	-command {
	    cd $dataDir
	    set dataSetChosen [GetChosenDataSets]
	    if {[llength $dataSetChosen] > 1} {set SRPlotSurveyStatus "Warning: Only first data set will be used in plotting."}
	    if [catch {plotSurveyData -first $first -last $last -dataSetChosen [lindex $dataSetChosen 0] \
			   -makePng $makePng -plotBpms 1 -outputRoot $outputRoot} result] {
		APSSetVarAndUpdate SRPlotSurveyStatus "plotSurveyData: $result"
	    }
	    cd $outputDir
	} -contextHelp "Plots measured data and adds BPM setpoints to the girder coordinates. The setpoints are taken from UBOP unless the program is started with command \"SRSuveyData -scrFile <full-filename>\""
    APSButton .plotHist -parent $w \
	-text "Plot history"  \
	-packOption "-side left" \
	-command {
	    cd $dataDir
	    if [catch {plotHistory -first $first -last $last} result] {
		APSSetVarAndUpdate SRPlotSurveyStatus "plotHistory: $result"
	    }
	    cd $outputDir
	} \
	-contextHelp "Plots history of measurements for selected sectors."
    return
}

proc plotHistory {args} {
    global dataDir
    APSParseArguments {first last}
    set tmpRoot /tmp/[APSTmpString]-surveyHist
    set dirList [FindDataSets]
    cd $dataDir
    foreach dir $dirList {
	#--- 1995 data are very different
	if {[string compare $dir 1995] != 0} {
	    if [file exists $dir/girder.break] {
		set filename $tmpRoot.$dir
		exec sddsprocess $dir/girder.break $filename "-redef=col,z,z 0 < ? z 1104 + : z \$" \
		    -print=para,DataNameParam,$dir -print=col,DataName,$dir \
		    -scan=col,DataValue,DataName,%lf -redef=col,PointOrder,i_row \
		    "-redef=col,DataValue,DataValue DataValue int - 3000 * 0.3 - DataValue int +"
		lappend fileList $filename
	    }
	}
    }
    eval exec sddscombine $fileList -pipe=out -merge \
	| sddssort -pipe -col=Sector \
	| sddsbreak -pipe -change=Sector \
	| sddssort -pipe -col=Girder \
	| sddsbreak -pipe -change=Girder \
	| sddssort -pipe -col=DataValue \
	| sddsconvert -pipe -del=col,xFit,yFit,xResidual,yResidual \
	| sddsprocess -pipe=in $tmpRoot.result -process=Sector,first,SectorParam \
	-process=Girder,first,GirderParam -filter=para,SectorParam,$first,$last \
	"\"-print=para,PlotTitle,Sector %1.0f Girder %1.0f,SectorParam,GirderParam\""
    eval file delete $fileList
    exec sddsplot -split=page -sep -topline=@PlotTitle -graph=sym \
	-col=DataName,x $tmpRoot.result &
    exec sddsplot -split=page -sep -topline=@PlotTitle -graph=sym  \
	-col=DataName,y $tmpRoot.result &
    exec sddsplot -split=page -sep -topline=@PlotTitle -graph=sym \
	-col=DataValue,y $tmpRoot.result &
}

proc CalculateAbsoluteOrbit {args} {
    global scrFile OAGGlobal
    APSParseArguments {bpmFile}

    set deleteFiles ""
    set tmpRoot /tmp/[APSTmpString]
    set twiFile $OAGGlobal(SRLatticesDirectory)/nux36nuy19/aps.twi
    set dataFile girder.break

    #--- Find bpm positions in absolute coordinates:
    set suffixList [list A:P1 B:P5 B:P1]
    set girderList [list 1    3    5   ]
    foreach plane [list x y] {
	set fileList ""
	foreach suffix $suffixList girder $girderList {
	    exec sddsprocess $twiFile -pipe=out -match=col,ElementName=S*$suffix \
		| sddsbreak -pipe=in $tmpRoot.$suffix -rowlimit=1
	    lappend deleteFiles $tmpRoot.$suffix
	    exec sddsprocess $dataFile -pipe=out -process=Girder,first,GirderParam -filter=para,GirderParam,$girder,$girder \
		| sddsinterp -pipe -col=z,${plane}Fit -fileValues=$tmpRoot.$suffix,col=s,parallel -above=extrap -below=extrap \
		| sddsxref -pipe $tmpRoot.$suffix -take=ElementName,ElementType \
		| sddscombine -pipe=in $tmpRoot.$suffix.${plane}posit -merge
	    lappend fileList $tmpRoot.$suffix.${plane}posit
	    lappend deleteFiles $tmpRoot.$suffix.${plane}posit
	}
	eval exec sddscombine $fileList -pipe=out -merge \
	    | sddsxref -pipe $twiFile -take=s -match=ElementName \
	    | sddssort -pipe -col=s \
	    | sddsconvert -pipe=in $tmpRoot.${plane}posit -rename=col,${plane}Fit=${plane}Position
	lappend deleteFiles $tmpRoot.${plane}posit
    }

    #--- Create files with BPM setpoints:
    foreach plane [list x y] {
	exec sddsprocess $scrFile -pipe=out \
	    "-match=col,ControlName=S*A:P1:ms:${plane}:SetpointAO,ControlName=S*B:P5:ms:${plane}:SetpointAO,|,ControlName=S*B:P1:ms:${plane}:SetpointAO,|" \
	    "-edit=col,ElementName,ControlName,%/:ms:$plane:SetpointAO//" \
	    -scan=col,${plane}Setpoint,ValueString,%lf,units=mm \
	    | sddsxref -pipe $twiFile -take=s -match=ElementName -nowarning \
	    | sddssort -pipe=in $tmpRoot.setpoints.$plane -col=s
	lappend deleteFiles $tmpRoot.setpoints.$plane
    }

    #--- Get orbit in absolute coordinates by adding setpoints to bpm positions:
    foreach plane [list x y] {
	exec sddsxref $tmpRoot.setpoints.$plane $tmpRoot.${plane}posit -pipe=out -take=${plane}Position -match=ElementName -nowarning \
	    | sddsprocess -pipe "-redef=col,${plane}OrbitSurvCoord,${plane}Setpoint ${plane}Position +" \
	    | sddsconvert -pipe=in $tmpRoot.absOrbit.$plane \
	    -retain=col,ElementName,${plane}Setpoint,s,${plane}Position,${plane}OrbitSurvCoord
	lappend deleteFiles $tmpRoot.absOrbit.$plane
    }
    exec sddsxref $tmpRoot.absOrbit.x $tmpRoot.absOrbit.y $bpmFile -take=ySetpoint,yPosition,yOrbitSurvCoord
    eval file delete $deleteFiles
}

proc plotSurveyData {args} {
    global dataDir outputDir pwd0
    set first 1
    set last  40
    set printer ""
    set dataSet ""
    set file ""
    set fileDevice ceps
    set printDevice cpost
    set plotBpms 0
    APSParseArguments {dataSetChosen first last plotBpms makePng outputRoot}

    if {[string compare [file dirname $outputRoot] "."] == 0} {
	set outputRoot1 $pwd0/$outputRoot
    } else {
	set outputRoot1 $outputRoot
    }
    if ![string length $outputRoot] {
	set tmpRoot /tmp/[APSTmpString].survey
    } else {
	if {[string compare [file dirname $outputRoot] "."] == 0} {
	    set tmpRoot $pwd0/$outputRoot
	} else {
	    set tmpRoot $outputRoot
	}
    }
    if {![string length $dataSetChosen] || ![string length $first] || \
          ![string length $last]} {
        return -code error "plotSurveyData: Invalid syntax."
    }
    #--- Common plot options/commands:
    if {[llength $dataSetChosen] > 1} {set layoutCommand " -layout=1,1 "} else {set layoutCommand " -layout=1,2 "}
    if {$first > $last} {
	set last [expr $last + 40]
    }
    # make 40 or so draw lines that are going to be present in all
    # sddsplot commands.
    for {set i $first} {$i <= [expr $last + 1]} {incr i} {
        lappend lineCommands -drawLine=x0value=[expr $i - 0.5],x1value=[expr $i - 0.5],q0value=0,q1value=1,linetype=2
    }

    set mainXPlotCommand ""
    set mainYPlotCommand ""
    set tempFileList ""
    set lineType 0
    foreach dataSet $dataSetChosen {
	if ![file exists $dataDir/$dataSet] {
	    return -code error "plotSurveyData: Can't find directory $dataDir/$dataSet."
	}
	if ![file exists $dataDir/$dataSet/data] {
	    return -code error "plotSurveyData: Can't find file $dataDir/$dataSet/data."
	}
	cd $dataDir/$dataSet
	set tempfile $tmpRoot.$dataSet
	set plotBpmCommandX ""
	set plotBpmCommandY ""
	if $plotBpms {
	    if [catch {CalculateAbsoluteOrbit -bpmFile $tempfile.bpms} result] {
		return -code error "CalculateAbsoluteOrbit: $result"
	    }
	    exec sddsprocess $tempfile.bpms $tempfile.bpms.1 "-redef=col,Sector,s 27.6 / 0.5 +"
	    exec sddsprocess $tempfile.bpms $tempfile.bpms.2 "-redef=col,Sector,s 27.6 / 40.5 +"
	    exec sddscombine $tempfile.bpms.1 $tempfile.bpms.2 $tempfile.bpms -overWrite
	    file delete $tempfile.bpms.1 $tempfile.bpms.2
	    set layoutCommand ""
	    set plotBpmCommandX " -col=Sector,xOrbitSurvCoord -graph=sym,type=2,fill,subt=1,scale=1 $tempfile.bpms -legend=spec=Setpoints "
	    set plotBpmCommandY " -col=Sector,yOrbitSurvCoord -graph=sym,type=2,fill,subt=1,scale=1 $tempfile.bpms -legend=spec=Setpoints "
	}

	#--- Some old files have 3 sectors before sector 1 and after sector 40, remove them:
	exec sddscombine girder.break -pipe=out -merge \
	    | sddsprocess -pipe -filter=col,z,0,1104 \
	    | sddsbreak -pipe -change=Girder \
	    | sddsprocess -pipe=in $tempfile.1 "-redef=col,Sector,z 27.6 / 0.5 +"
	exec sddscombine girder.break -pipe=out -merge \
	    | sddsprocess -pipe -filter=col,z,0,1104 \
	    | sddsbreak -pipe -change=Girder \
	    | sddsprocess -pipe=in $tempfile.2 "-redef=col,Sector,z 27.6 / 40.5 +"
	exec sddscombine $tempfile.1 $tempfile.2 $tempfile -overWrite
	lappend tempFileList $tempfile
	file delete $tempfile.1 $tempfile.2
	append mainXPlotCommand " -col=Sector,x $tempfile -grap=dots,sub=3,type=$lineType -leg=spec=$dataSet \"-ylabel=x (mm)\" -col=Sector,xFit $tempfile -grap=line,type=$lineType -leg=spec=Fit -split=pages "
	append mainYPlotCommand " -col=Sector,y $tempfile -grap=dots,sub=3,type=$lineType -leg=spec=$dataSet \"-ylabel=y (mm)\" -col=Sector,yFit $tempfile -grap=line,type=$lineType -leg=spec=Fit -split=pages "
	incr lineType
    }
    set xDiffPlotCommand ""
    set yDiffPlotCommand ""
    set zDiffPlotCommand ""
    set N [llength $tempFileList]
    if {$N > 1} {
	set lineType 0
	set diffFile $tmpRoot.diff
	exec sddsconvert [lindex $tempFileList 0] $diffFile -rename=col,x=x0 -rename=col,y=y0 -rename=col,z=z0
	for {set i 1} {$i < $N} {incr i} {
	    set dataSet [lindex $dataSetChosen $i]
	    if [catch {exec sddsxref $diffFile [lindex $tempFileList $i] -pipe=out -nowarning \
			   -take=x,y,z -rename=col,x=x-$dataSet -rename=col,y=y-$dataSet -rename=col,z=z-$dataSet \
			   | sddsprocess -pipe=in $diffFile.tmp "-redef=col,xDiff-$dataSet,x-$dataSet x0 -" \
			   "-redef=col,yDiff-$dataSet,y-$dataSet y0 -" "-redef=col,zDiff-$dataSet,z-$dataSet z0 -"} result] {
		return -code error "Error taking columns (diffFile: $diffFile, source file: [lindex $tempFileList $i]): $result"
	    }
	    #--- Calculating fast rms differences to get idea on measurement accuracy:
	    if [catch {exec sddscombine $diffFile.tmp -pipe=out -merge \
			   | tee $diffFile.tmp1 \
			   | sddssmooth -pipe -col=Sector,xDiff-$dataSet,yDiff-$dataSet -points=7 -passes=1 \
			   | sddsxref -pipe $diffFile.tmp1 -take=xDiff-$dataSet,yDiff-$dataSet \
			   -rename=col,xDiff-$dataSet=xDiffRaw-$dataSet -rename=col,yDiff-$dataSet=yDiffRaw-$dataSet \
			   | sddsprocess -pipe \
			   "-redef=col,xDiffFast-$dataSet,xDiffRaw-$dataSet xDiff-$dataSet -" \
			   "-redef=col,yDiffFast-$dataSet,yDiffRaw-$dataSet yDiff-$dataSet -" \
			   -process=xDiffFast-$dataSet,stand,StdX -process=yDiffFast-$dataSet,stand,StdY \
			   | sdds2stream -pipe=in -para=StdX,StdY} stdList] {
		return -code error "Error calculating fast rms difference: $stdList"
	    }
	    exec sddsprocess $diffFile.tmp $diffFile -redef=para,diffXrms-$dataSet,[lindex $stdList 0] \
		-redef=para,diffYrms-$dataSet,[lindex $stdList 1]
	    file delete $diffFile.tmp $diffFile.tmp1
	    APSSetVarAndUpdate SRPlotSurveyStatus "Fast rms differences ($dataSet minus [lindex $dataSetChosen 0]): x: [format %8.2e [lindex $stdList 0]](mm); y: [format %8.2e [lindex $stdList 1]](mm)"
	    append xDiffPlotCommand " -col=Sector,xDiff-$dataSet -graph=dot,sub=3,type=$lineType \"-leg=spec=Diff $dataSet\" $diffFile "
	    append yDiffPlotCommand " -col=Sector,yDiff-$dataSet -graph=dot,sub=3,type=$lineType \"-leg=spec=Diff $dataSet\" $diffFile "
	    append zDiffPlotCommand " -col=Sector,zDiff-$dataSet -graph=dot,sub=3,type=$lineType \"-leg=spec=Diff $dataSet\" $diffFile "
	    incr lineType
	}
	append xDiffPlotCommand " \"-topline=Difference from [lindex $dataSetChosen 0]\" \"-ylabel=Diff x (mm)\""
	append yDiffPlotCommand " \"-topline=Difference from [lindex $dataSetChosen 0]\" \"-ylabel=Diff y (mm)\""
	append zDiffPlotCommand " \"-topline=Difference from [lindex $dataSetChosen 0]\" \"-ylabel=Diff z (m)\""
	set topline "\"-topline=SR alignment data\""
    } else {
	set topline "\"-topline=$dataSet data set\""
    }

    set filterScaleTicksCommand " -filter=col,Sector,[expr $first - 0.5],[expr $last + 0.5] -scale=[expr $first - 0.5],[expr $last + 0.5],0,0 -ticksettings=xspacing=1.0,xlinetype=2,xsize=0 "
    eval exec sddsplot $topline \
	$layoutCommand -axes=x \
	$filterScaleTicksCommand \
	$lineCommands \
	$plotBpmCommandX \
	$mainXPlotCommand -end \
	$plotBpmCommandY \
	$mainYPlotCommand -end \
	$xDiffPlotCommand -end \
	$yDiffPlotCommand -end \
	$zDiffPlotCommand -end &
    if $makePng {
	if {$makePng == 1} {
	    set device lpng
	    set ext png
	} else {
	    set device ceps
	    set ext eps
	}
	eval exec sddsplot -thickness=2 -linetype=0,thickness=2 \
	    $topline -axes=x,linetype=1,thick=2 \
	    $filterScaleTicksCommand \
	    $lineCommands \
	    $plotBpmCommandX \
	    $mainXPlotCommand \
	    -device=$device -output=$tempfile.x.$ext
	eval exec sddsplot -thickness=2 -linetype=0,thickness=2 \
	    $topline -axes=x,linetype=1,thick=2 \
	    $filterScaleTicksCommand \
	    $lineCommands \
	    $plotBpmCommandY \
	    $mainYPlotCommand \
	    -device=$device -output=$tempfile.y.$ext
	eval exec sddsplot -layout=1,2 -thickness=2 -linetype=0,thickness=2 \
	    $topline -axes=x,linetype=1,thick=2 \
	    $filterScaleTicksCommand \
	    $lineCommands \
	    $plotBpmCommandX \
	    $mainXPlotCommand -end \
	    $plotBpmCommandY \
	    $mainYPlotCommand \
	    -device=$device -output=$tempfile.xy.$ext
	APSSetVarAndUpdate SRPlotSurveyStatus "Png files were saved in /tmp dir: $tempfile.x.$ext and $tempfile.y.$ext $tempfile.xy.$ext"
    }

    APSSetVarAndUpdate SRPlotSurveyStatus "Done."
    return
}

proc SmoothData {args} {
    APSParseArguments {dataFile first last sectorFitRange tmpRoot outputFile polynom}
    set deleteFiles ""
    set zLo [expr ($first - 1) * 27.6]
    set zHi [expr  $last * 27.6]
    set sectorAround [expr int(($sectorFitRange - 1) / 2)]
    set circum 1104
    set sectorL 27.6
    set zNeg [expr $sectorL * $sectorAround * -1]
    set zPos [expr $sectorL * $sectorAround + $circum]
    exec sddsprocess $dataFile $tmpRoot \
      "-redef=col,Sector,z $sectorL / 0.5 +" \
      "-redef=col,Sector0,z $sectorL /"
    exec sddsprocess $tmpRoot $tmpRoot.1 "-redef=col,z,z $circum -" \
	"-redef=col,Sector,Sector 40 -" "-redef=col,Sector0,Sector0 40 -" 
    exec sddsprocess $tmpRoot $tmpRoot.2 "-redef=col,z,z $circum +" \
	"-redef=col,Sector,Sector 40 +" "-redef=col,Sector0,Sector0 40 +" 
    exec sddscombine $tmpRoot.1 $tmpRoot $tmpRoot.2 -merge -pipe=out \
	| sddsprocess -pipe=in $tmpRoot.comb 
    lappend deleteFiles $tmpRoot.1 $tmpRoot $tmpRoot.2 $tmpRoot.comb
    set fileList ""
    if {$last > 40} {set loopLimit [expr $last + 1]} else {set loopLimit 41}
    #------ First smoothing:
    for {set i 1} {$i < $loopLimit} {incr i} {
	set zNeg [expr $sectorL * ($i-1) - $sectorL * $sectorAround]
	set zPos [expr $sectorL * $i  + $sectorL * $sectorAround]
	set zNeg1 [expr $sectorL * ($i-1)]
	set zPos1 [expr $sectorL * $i]
	set xOffset [expr $sectorL * ($i-0.5)]
	if [catch {exec sddsprocess $tmpRoot.comb -pipe=out -filter=col,z,$zNeg,$zPos \
		       | sddsmpfit -pipe -indep=z -depend=x,y -terms=$polynom -xOffset=$xOffset \
		       | sddsprocess -pipe=in $tmpRoot.S$i -filter=col,z,$zNeg1,$zPos1} result] {
	    return -code error "Error processing combined file $tmpRoot.comb, i= $i"
	}
	lappend fileList $tmpRoot.S$i
    }
    eval exec sddscombine $fileList -merge $tmpRoot.pfit.comb
    lappend deleteFiles $tmpRoot.pfit.comb
    exec sddsprocess $tmpRoot.comb -pipe=out -filter=col,z,0,$circum \
	| sddsxref -pipe $tmpRoot.pfit.comb -take=xFit,yFit -equate=z \
	-rename=col,xFit=xSmoothed -rename=col,yFit=ySmoothed \
	| sddsprocess -pipe "-redef=col,xDiff,x xSmoothed -" "-redef=col,yDiff,y ySmoothed -" \
	"-redef=col,xDiffAbs,xDiff abs" "-redef=col,yDiffAbs,yDiff abs" \
	| sddsbreak -pipe -change=Girder \
	| sddsprocess -pipe=in $outputFile -process=xDiff,stand,xDiffStd -process=yDiff,stand,yDiffStd \
	-process=xDiffAbs,max,xDiffMax -process=yDiffAbs,max,yDiffMax \
	-process=Girder,first,GirderNumber "-redef=col,Sector0,z $sectorL / int 1 +" \
	-process=Sector0,first,SectorNumber -nowarning
    eval file delete $deleteFiles $fileList
}

proc plotSmoothedSurveyData {args} {
    global dataDir outputDir pwd0
    set first 1
    set last  40
    set printer ""
    set dataSet ""
    set file ""
    set fileDevice ceps
    set printDevice cpost
    set makePng 0
    set plotBpms 0
    set outputRoot ""
    APSParseArguments {dataSet first last sectorFitRange polynom makePng analysis nPrintout outputRoot}
    
    if {![string length $dataSet] || ![string length $first] || \
	    ![string length $last]} {
	return -code error "plotSurveyData: Invalid syntax."
    }
    
    if ![file exists $dataSet] {
        return -code error "plotSurveyData: Can't find directory $dataSet."
    }
    cd $dataSet

    if {[string compare [file dirname $outputRoot] "."] == 0} {
	set outputRoot1 $pwd0/$outputRoot
    } else {
	set outputRoot1 $outputRoot
    }
    if ![string length $outputRoot] {
	set tmpRoot /tmp/[APSTmpString].survey
    } else {
	if {[string compare [file dirname $outputRoot] "."] == 0} {
	    set tmpRoot $pwd0/$outputRoot
	} else {
	    set tmpRoot $outputRoot
	}
    }
    if {$first > $last} {
	set last [expr $last + 40]
    }
    # make 40 or so draw lines that are going to be present in all sddsplot commands.
    for {set i $first} {$i <= [expr $last + 1]} {incr i} {
        lappend lineCommands -drawLine=x0value=[expr $i - 0.5],x1value=[expr $i - 0.5],q0value=0,q1value=1,linetype=2
    }

    #--- First smoothing:
    if [catch {SmoothData -dataFile girder.break -first $first -last $last -sectorFitRange $sectorFitRange -polynom $polynom \
		   -tmpRoot $tmpRoot -outputFile $tmpRoot.final} result] {
	return -code error "SmoothData 1: $result"
    }
    set diffRms [exec sddscombine $tmpRoot.final -pipe=out -merge \
		     | sddsprocess -pipe -process=xDiff,rms,xRms -process=yDiff,rms,yRms \
		     | sdds2stream -pipe=in -para=xRms,yRms]

    set nSigma 2
    exec sddsprocess $tmpRoot.final -pipe=out \
	"-redef=para,UseGirderX,xDiffMax [lindex $diffRms 0] $nSigma * < ? 1 : 0 \$" \
	"-redef=para,UseGirderY,yDiffMax [lindex $diffRms 1] $nSigma * < ? 1 : 0 \$" \
	| sddsprocess -pipe "-redef=col,x,UseGirderX 1 == ? x : xSmoothed \$" "-redef=col,y,UseGirderY 1 == ? y : ySmoothed \$" \
	| sddsconvert -pipe=in $tmpRoot.smooth.1 -del=col,xSmoothed,ySmoothed,xDiff,yDiff,xDiffAbs,yDiffAbs,Sector0 \
	-del=para,NumberCombined,xDiffStd,yDiffStd,xDiffMax,yDiffMax,GirderNumber,SectorNumber,UseGirderX,UseGirderY
    lappend deleteFiles $tmpRoot.smooth.1
    #--- Second smoothing:
    if [catch {SmoothData -dataFile $tmpRoot.smooth.1 -first $first -last $last -sectorFitRange $sectorFitRange -polynom $polynom \
		   -tmpRoot $tmpRoot -outputFile $tmpRoot.final.1} result] {
	return -code error "SmoothData 2 (dataFile: $tmpRoot.smooth.1): $result"
    }
    lappend deleteFiles $tmpRoot.final.1
    exec sddsconvert $tmpRoot.final -pipe=out -del=col,xSmoothed,ySmoothed \
	-del=para,xDiffStd,yDiffStd,xDiffMax,yDiffMax \
	| sddsxref -pipe $tmpRoot.final.1 -take=xSmoothed,ySmoothed \
	| sddsprocess -pipe "-redef=col,xDiff,x xSmoothed -" "-redef=col,yDiff,y ySmoothed -" \
	"-redef=col,xDiffAbs,xDiff abs" "-redef=col,yDiffAbs,yDiff abs" \
	| sddsprocess -pipe=in $tmpRoot.final.2 -process=xDiff,stand,xDiffStd -process=yDiff,stand,yDiffStd \
	-process=xDiffAbs,max,xDiffMax -process=yDiffAbs,max,yDiffMax -redef=para,Index,i_page \
	"-redef=para,SectorPlot,SectorNumber 1 - GirderNumber 5 / +" -nowarning
    file copy -force $tmpRoot.final.2 $tmpRoot.final
    lappend deleteFiles $tmpRoot.final.2

    #--- Printout of bad bpms:
    if !$plotBpms {
	switch -exact $analysis {
	    stand {set sortParam DiffStd}
	    maximum {set sortParam DiffMax}
	}
	exec sddssort $tmpRoot.final -pipe=out -para=x$sortParam,decreasing \
	    | sddsprocess -pipe=in $tmpRoot.final.sortx -redef=para,Index,i_page
	exec sddssort $tmpRoot.final -pipe=out -para=y$sortParam,decreasing \
	    | sddsprocess -pipe=in $tmpRoot.final.sorty -redef=para,Index,i_page
	set xRms [exec sddscollapse $tmpRoot.final -pipe=out \
		      | sddsprocess -pipe -process=x$sortParam,rms,Rms \
		      | sdds2stream -pipe=in -para=Rms]
	set yRms [exec sddscollapse $tmpRoot.final -pipe=out \
		      | sddsprocess -pipe -process=y$sortParam,rms,Rms \
		      | sdds2stream -pipe=in -para=Rms]
	set xList [join [exec sdds2stream $tmpRoot.final.sortx -para=x$sortParam,GirderNumber,SectorNumber] ]
	set yList [join [exec sdds2stream $tmpRoot.final.sorty -para=y$sortParam,GirderNumber,SectorNumber] ]
	APSSetVarAndUpdate SRPlotSurveyStatus "Worst displaced girders (based on $analysis):"
	for {set i 0} {$i < $nPrintout} {incr i} {
	    set xString "Sector [format %2.0f [lindex $xList [expr $i*3 + 2]]]; Girder [format %1.0f [lindex $xList [expr $i*3 + 1]]]; Deviation X: [format %6.3f [lindex $xList [expr $i*3]]]."
	    set yString "Sector [format %2.0f [lindex $yList [expr $i*3 + 2]]]; Girder [format %1.0f [lindex $yList [expr $i*3 + 1]]]; Deviation Y: [format %6.3f [lindex $yList [expr $i*3]]]."
	    APSSetVarAndUpdate SRPlotSurveyStatus "$xString -- $yString"
	}
    }

    if $makePng {
	if {$makePng == 1} {
	    set device lpng
	    set ext png
	} else {
	    set device ceps
	    set ext eps
	}
	eval exec sddsplot -thickness=2 -linetype=0,thickness=2 \
	    \"-topline=$dataSet data set\" \
	    -layout=1,2 \
	    -axes=x $tmpRoot.final \
	    -filter=col,Sector,[expr $first - 0.5],[expr $last + 0.5] \
	    -scale=[expr $first - 0.5],[expr $last + 0.5],0,0 \
	    -ticksettings=xspacing=1.0,xlinetype=2,xsize=0 \
	    $lineCommands \
	    -col=Sector,x  -grap=dots,sub=1 -leg=spec=Data \"-ylabel=x (mm)\" \
	    -col=Sector,xFit -grap=line,type=0 -leg=spec=Fit -split=pages \
	    -col=Sector,xSmoothed -graph=line,type=1 -leg=spec=Smoothed -end \
	    -col=Sector,y  -grap=dots,sub=1 -leg=spec=Data \"-ylabel=y (mm)\" \
	    -col=Sector,yFit -grap=line,type=0 -leg=spec=Fit -split=pages \
	    -col=Sector,ySmoothed -graph=line,type=1 -leg=spec=Smoothed \
	    -device=$device -output=/tmp/survey-smooth-1.$ext
	eval exec sddsplot -thickness=2 -linetype=0,thickness=2 \
	    \"-topline=$dataSet data set\" \
	    -layout=1,2 \
	    -axes=x $tmpRoot.final \
	    -filter=col,Sector,[expr $first - 0.5],[expr $last + 0.5] \
	    -scale=[expr $first - 0.5],[expr $last + 0.5],0,0 \
	    -ticksettings=xspacing=1.0,xlinetype=2,xsize=0 \
	    $lineCommands \
	    -col=Sector,xDiff -grap=symb,scale=0.75,fill -leg=spec=Diff  \"-ylabel=x (mm)\" -end \
	    -col=Sector,yDiff -grap=symb,scale=0.75,fill -leg=spec=Diff  \"-ylabel=y (mm)\" \
	    -device=$device -output=/tmp/survey-smooth-2.$ext
	APSSetVarAndUpdate SRPlotSurveyStatus "Png files were saved in /tmp dir."
    }
    eval exec sddsplot \"-topline=$dataSet data set\" \
	-axes=x $tmpRoot.final \
	-filter=col,Sector,[expr $first - 0.5],[expr $last + 0.5] \
	-scale=[expr $first - 0.5],[expr $last + 0.5],0,0 \
	-ticksettings=xspacing=1.0,xlinetype=2,xsize=0 \
	$lineCommands \
	-col=Sector,x  -grap=dots,sub=2 -leg=spec=Data \"-ylabel=x (mm)\" \
	-col=Sector,xFit -grap=line,type=3 -leg=spec=Fit -split=pages \
	-col=Sector,xSmoothed -graph=line,type=4 -leg=spec=Smoothed -end \
	-col=Sector,y  -grap=dots,sub=2 -leg=spec=Data \"-ylabel=y (mm)\" \
	-col=Sector,yFit -grap=line,type=3 -leg=spec=Fit -split=pages \
	-col=Sector,ySmoothed -graph=line,type=4 -leg=spec=Smoothed &
    eval exec sddsplot \"-topline=$dataSet data set\" \
	-axes=x $tmpRoot.final \
	-filter=col,Sector,[expr $first - 0.5],[expr $last + 0.5] \
	-scale=[expr $first - 0.5],[expr $last + 0.5],0,0 \
	-ticksettings=xspacing=1.0,xlinetype=2,xsize=0 \
	$lineCommands \
	-col=Sector,xDiff -grap=symb,scale=0.75,fill -leg=spec=Diff  \"-ylabel=x (mm)\" -end \
	-col=Sector,yDiff -grap=symb,scale=0.75,fill -leg=spec=Diff  \"-ylabel=y (mm)\" &
    set xTitle "Rms of x$sortParam is [format %.3f $xRms] mm"
    set yTitle "Rms of y$sortParam is [format %.3f $yRms] mm"
    exec sddsplot -graph=symbol "-topline=Deviation from smooth line"\
	-para=Index,x$sortParam "-title=$xTitle" $tmpRoot.final.sortx -end \
	-para=Index,y$sortParam "-title=$yTitle" $tmpRoot.final.sorty &

    eval file delete $deleteFiles
    APSSetVarAndUpdate SRPlotSurveyStatus "Done."
    return
}

set first 1
set last 40
set printer diag01
set printDevice cpost
set fileDevice ceps
set dataDir /home/helios/oagData/sr/alignmentData
set outputDir [pwd]
set outputfile ""
set sectorFitRange 3
set polynom 9
set makePng 0
set analysis stand
set nPrintout 10
set outputRoot ""
set pwd0 [exec pwd]
set realMeasurementList [list 2003.0003 2005.0002 2007.0001 2009.0002 2011.0003 2013.0003 2015.0001]

#--- To substitute bpm setpoint file if needed:
set args $argv
set scrFile ""
APSParseArguments {scrFile}
if ![string length $scrFile] {
    set scrFile /home/helios/oagData/SCR/snapshots/SR/SR-UserBeamPreferred.gz
}

set dataSet [lindex [FindDataSets] end]

MakeInputFrame .input -parent .userFrame
MakePlotInputFrame .plotInput -parent .userFrame
MakePlotCommandFrame .plotCommand -parent .userFrame

