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

set usage "generateResponseWithErrors -machineName <APS|TAA> -lteFile <filename> -makeBpmNamesUnique <0|1> -beamline <beamline-name> \
   -paramFileList <file-list> -errorList <number-list> -definitionFile <filename> \
   -elementListFile <filename> -rootname <rootname> -seed <number> -workDir <dirname> \[-kick <number>\] \
   \[-calculateBeamMoments <0|1> -rfBeamlineName <beamline-name>\] \
   \[-useKickFiles <0|1> -kickFileX <filename> -kickFileY <filename>\] \
   \[-correctTunes <0|1> -knobFile <filename>\] \[-correctOrbit <0|1>\] \[-removeAverageBpmError <0|1>\] \
   \[-verbose <0|1>\] \[-responseOnly <0|1>\] \[-calculateBeamMoments <0|1>\]"
if [info exists env(LOCO_BINDIR)] {
    set locoBinDir $env(LOCO_BINDIR)
} else {
    puts stderr "Error: LOCO_BINDIR environment variable is not defined"
    exit
}
if [info exists env(LOCO_TMPDIR)] {
    set tmpDir $env(LOCO_TMPDIR)
} else {
    set tmpDir $env(HOME)/tmp
}
if ![file exists $tmpDir] {exec mkdir -p $tmpDir}
set auto_path [linsert $auto_path 0 $locoBinDir/tclLib]
set tmpRoot $tmpDir/[APSTmpString]-genErr

set args $argv
set argCopy $args

set requiredVars [list lteFile beamline errorList elementListFile rootname seed workDir \
		      definitionFile makeBpmNamesUnique machineName kick useKickFiles]
foreach var $requiredVars {set $var ""}
APSParseArguments $requiredVars

set nonrequiredVars [list paramFileList removeAverageBpmError verbose responseOnly correctTunes \
			 calculateBeamMoments rfBeamlineName correctOrbit knobFile transform2measuredFormat \
			 outputTwissFile logFile kickFileX kickFileY]
foreach var $nonrequiredVars {set $var ""}
set correctTunes 0
set correctOrbit 0
set removeAverageBpmError 1
set verbose 0
set responseOnly 0
set transform2measuredFormat 0
set calculateBeamMoments 0
APSParseArguments $nonrequiredVars

set error 0
foreach var $requiredVars {
    if ![string length [set $var]] {set error 1; puts stderr "Error: $var is empty."}
}
if $calculateBeamMoments {
    if ![string length $rfBeamlineName] {set error 1; puts stderr "Error: rfBeamlineName is empty with calculateBeamMoments=1."}
}
if $error {
    puts stderr "Calling arguments: $argCopy"
    puts stderr $usage
    exit
}

#------ Make some files local (it is possible that individual nodes don't have access to remote file storage):
set copyfileList [list lteFile knobFile]
foreach filenameVar $copyfileList {
    if [string length [set $filenameVar]] {
	if {[string compare [set $filenameVar] $workDir/[file tail [set $filenameVar]]] != 0} {
	    file copy -force [set $filenameVar] $workDir/[file tail [set $filenameVar]]
	    set $filenameVar $workDir/[file tail [set $filenameVar]]
	}
    }
}
if [string length $paramFileList] {
    set newParamFileList ""
    foreach filename $paramFileList {
	if {[string compare $filename $workDir/[file tail $filename]] != 0} {
	    file copy -force $filename $workDir/[file tail $filename]
	    lappend newParamFileList $workDir/[file tail $filename]
	} else {
	    lappend newParamFileList $filename
	}
    }
    set paramFileList $newParamFileList
}


#-------------------------------------------------------------------------------------------------------------------------

proc OutputMessage {args} {
    set logFile ""
    APSParseArguments {text verbose logFile}
    if $verbose {puts stdout $text}
    if [string length $logFile] {
        if [catch {open $logFile a} fid] { return -code error "$fid" }
	puts $fid $text
	close $fid
    }
}

#-------------------------------------------------------------------------------------------------------------------------

proc RemoveAllSpaces {line} {
    set strLength [string length $line]
    set line1 ""
    for {set I 0} {$I < $strLength} {incr I} {
	if {[string compare " " [string range $line $I $I]] != 0} {
	    append line1 [string range $line $I $I]
	}
    }
    return $line1
}

#-------------------------------------------------------------------------------------------------------------------------

proc CalculateMoments {args} {
    global tmpDir bRho deleteFiles
    APSParseArguments {lteFile paramFileList rfBeamlineName rootname}

    set tmpRoot $tmpDir/[APSTmpString]-mom
    set eleFile $tmpRoot.ele
    lappend deleteFiles $eleFile
    set energy [format %10.4e [expr $bRho * 299792458e-6]]
    if [catch {Fit_GenerateElegantFileFromLTE1 -eleOutputFile $eleFile \
		   -run_setup [list "lattice $lteFile use_beamline $rfBeamlineName rootname $rootname default_order 2 p_central_mev $energy"] \
		   -load_parameters [list "filename_list \"$paramFileList\""] \
		   -alter_elements [list "name * type KQUAD item N_KICKS value 50" "name * type KSEXT item N_KICKS value 3" \
					"name * type CSBEN* item N_KICKS value 100" "name * type CSBEN* item EDGE_ORDER value 1" \
					"name * type CSBEN* item INTEGRATION_ORDER value 4" \
					"name * type KQUAD item ISR value 1" "name * type CSBEN* item ISR value 1" \
					"name * type KQUAD item SYNCH_RAD value 1" "name * type CSBEN* item SYNCH_RAD value 1"] \
		   -closed_orbit [list "output $rootname.mom.orb"] \
		   -twissOutput [list "filename $rootname.mom.twi radiation_integrals 1"] \
		   -moments_output [list "filename $rootname.mom n_slices 100"] \
		   -run_control [list "n_steps 1"] \
		   -bunched_beam [list "n_particles_per_bunch 1"] \
	       } result] {
	return -code error "Fit_GenerateElegantFileFromLTE1: $result"
    }
    catch {file delete $eleFile.log}
    if [catch {exec elegant $eleFile > $eleFile.log} result] {
	return -code error "Error running elegant (see $eleFile.log): $result"
    }
    lappend deleteFiles $eleFile $rootname.mom.orb $rootname.mom.twi $eleFile.log
}

#-------------------------------------------------------------------------------------------------------------------------

proc ApplyCorrectorCalibrationCorrection {args } {
    global tmpDir deleteFiles
    APSParseArguments { hrmFile vrmFile hrmXFile vrmXFile hcorFile vcorFile}

    set tmpRoot $tmpDir/[APSTmpString]-calibCorr
    set hList [list $hrmFile $hrmXFile]
    set vList [list $vrmFile $vrmXFile]
    foreach fileList [list $hList $vList] corrFile [list $hcorFile $vcorFile] {
	if [exec sdds2stream $corrFile -rows=bare] {
	    foreach calcFile $fileList {
		set rows [lindex [exec sdds2stream $calcFile -rows=bare] 0]
		if [catch {exec sddsprocess $calcFile -pipe=out -reprint=col,BPMName,%s%s,BPMName,Plane \
			       | sddscombine -pipe -merge \
			       | sddstranspose -pipe -oldColumnNames=CorrectorNameValue -newColumnNames=BPMName \
			       | sddsxref -pipe $corrFile -fillIn -take=ParameterValue -match=CorrectorNameValue=ElementName \
			       | sddsprocess -pipe "-redef=col,%s,%s 1 ParameterValue + *,select=*,exclude=*Value" \
			       | sddsconvert -pipe -del=col,ParameterValue -del=para,* \
			       | sddstranspose -pipe -oldColumnNames=BPMName -newColumnNames=CorrectorNameValue \
			       | sddsprocess -pipe "-reedit=col,BPMName,e 1b 1d" \
			       | sddsbreak -pipe -rowlimit=$rows \
			       | sddsxref -pipe=in $calcFile $tmpRoot.out -leave=* -transfer=para,* } result] {
		    return -code error "Error applying calibration correction (calcFile: $calcFile; corrFile $corrFile): $result"
		}
		file copy -force $tmpRoot.out $calcFile
	    }
	}
    }
    lappend deleteFiles $tmpRoot.out
}

#-------------------------------------------------------------------------------------------------------------------------
#------ Xbpm = ( Xorb * Cos A + Yorb * Sin A) * (1 + Gx)
#------ Ybpm = (-Xorb * Sin A + Yorb * Cos A) * (1 + Gy)
#------ where Zbpm  -  bpm reading
#------       Zorb  -  real orbit
#------          A  -  tilt
#------         Gz  -  bpm gain error
#---
proc ApplyBPMCorrections { args } {
    
    global tmpDir options deleteFiles
    APSParseArguments { hrmFile hrmXFile vrmFile vrmXFile elementFileRoot coupledMatrix bpmNoise seed}
    
    set tmpRoot $tmpDir/[APSTmpString]-bpmCorrect

    set xbpmTiltFile $elementFileRoot.xbpmTilt.param
    set ybpmTiltFile $elementFileRoot.ybpmTilt.param
    set xbpmGainFile $elementFileRoot.xbpm.param
    set ybpmGainFile $elementFileRoot.ybpm.param

    set doTiltCorrection 1

    #------ Tilt correction
    if $doTiltCorrection {
	set xbpms [lindex [exec sdds2stream $hrmFile -rows=bare] 0]

	exec sddsconvert $hrmFile $tmpRoot.xbpms -keep=1 -retain=col,BPMName -rename=col,BPMName=ElementName
	exec sddsconvert $hrmFile $tmpRoot.ybpms -keep=2 -retain=col,BPMName -rename=col,BPMName=ElementName
	lappend deleteFiles $tmpRoot.xbpms $tmpRoot.ybpms
	exec sddsxref $tmpRoot.xbpms $xbpmTiltFile -pipe=out -take=ParameterValue -match=ElementName -fill -nowarning \
	    | sddsprocess -pipe=in $xbpmTiltFile.full -print=col,ElementParameter,TILT \
	    -print=col,ParameterMode,DIFFERENTIAL -print=col,VariableType,xBpmTilt
	exec sddsxref $tmpRoot.ybpms $ybpmTiltFile -pipe=out -take=ParameterValue -match=ElementName -fill -nowarning \
	    | sddsprocess -pipe=in $ybpmTiltFile.full -print=col,ElementParameter,TILT \
	    -print=col,ParameterMode,DIFFERENTIAL -print=col,VariableType,yBpmTilt

	exec sddsprocess $xbpmTiltFile.full $tmpRoot.sin1 "-redef=col,SinValue,ParameterValue sin"
	exec sddsprocess $ybpmTiltFile.full $tmpRoot.sin2 "-redef=col,SinValue,ParameterValue sin -1 *"
	exec sddscombine $tmpRoot.sin1 $tmpRoot.sin2 $tmpRoot.crossVector -merge -overWrite

	exec sddscombine $xbpmTiltFile.full $ybpmTiltFile.full -pipe=out -merge \
	    | sddsprocess -pipe=in $tmpRoot.directVector "-redef=col,CosValue,ParameterValue cos"

	lappend deleteFiles $tmpRoot.sin1 $tmpRoot.sin2 $tmpRoot.directVector $tmpRoot.crossVector $xbpmTiltFile.full $ybpmTiltFile.full

	foreach rmFile [list $hrmFile $vrmFile $hrmXFile $vrmXFile] \
	    vectorFile [list $tmpRoot.directVector $tmpRoot.directVector $tmpRoot.crossVector $tmpRoot.crossVector] \
	    columnName [list CosValue CosValue SinValue SinValue] \
	    extName [list hDirect vDirect hCross vCross] {
		if [catch {exec sddscombine $rmFile -pipe=out -merge \
			       | sddsxref -pipe $vectorFile -nowarning -fillIn -take=$columnName -match=BPMName=ElementName \
			       | sddsconvert -pipe -rename=col,BPMName=BPMNameValue \
			       | sddsprocess -pipe "-redef=col,%s,%s $columnName *,select=*,exclude=*Value" \
			       | sddsconvert -pipe=in $tmpRoot.$extName -rename=col,BPMNameValue=BPMName \
			       -del=col,$columnName} result] {
		    return -code error "Error applying bpm tilts(rmFile $rmFile; vectorFile $vectorFile): $result"
		}
		lappend deleteFiles $tmpRoot.$extName
	    }
	exec sddsmatrixop $tmpRoot.hDirect -pipe=out -push=$tmpRoot.hCross -add \
	    | sddsbreak -pipe -rowlimit=$xbpms \
	    | sddsxref -pipe=in $hrmFile $tmpRoot.hResult -take=BPMName -transfer=para,*
	exec sddsmatrixop $tmpRoot.vDirect -pipe=out -push=$tmpRoot.vCross -add \
	    | sddsbreak -pipe -rowlimit=$xbpms \
	    | sddsxref -pipe=in $vrmFile $tmpRoot.vResult -take=BPMName -transfer=para,*
	lappend deleteFiles $tmpRoot.hResult $tmpRoot.vResult
	file copy -force $tmpRoot.hResult $hrmFile
	file copy -force $tmpRoot.vResult $vrmFile
    }

    #------ Gain correction
    set rmFileList [list $hrmFile $vrmFile]
    set planeList [list X Y]
    set bpmFile $tmpRoot.bpmGain
    foreach rmFile $rmFileList plane $planeList {
	switch -regexp -- $coupledMatrix {
	    0|1 { 
		switch -exact -- $plane {
		    X {set bpmFile $xbpmGainFile}
		    Y {set bpmFile $ybpmGainFile}
		}
	    }
	    2 {exec sddscombine $xbpmGainFile $ybpmGainFile $bpmFile -overWrite; lappend deleteFiles $bpmFile}
	}
	if [exec sddscombine $bpmFile -pipe=out -merge | sdds2stream -pipe=in -rows=bare] {
	    if [catch {exec sddsconvert $rmFile -pipe=out -rename=col,BPMName=BPMNameValue \
			   | sddsxref -nowarning -pipe $bpmFile -fillIn -take=ParameterValue -match=BPMNameValue=ElementName \
			   | sddsprocess -pipe "-redef=col,%s,%s 1 ParameterValue + *,select=*,exclude=*Value" \
			   | sddsconvert -pipe=in $tmpRoot.gainResult -del=col,ParameterValue \
			   -rename=col,BPMNameValue=BPMName} result] {
		return -code error "BPM gain correction error: $result"
	    }
	    file copy -force $tmpRoot.gainResult $rmFile
	    lappend deleteFiles $tmpRoot.gainResult 
	}
    }

    #------ Adding bpm noise (dispersion is without noise for now):
    if {$bpmNoise > 0} {
	set rmFile $hrmFile
	incr seed 5000
	exec sddsprocess $rmFile -pipe=out "-rpnexpression=$seed srnd" \
	    "-redef=col,%s,grnd $bpmNoise *,select=*,exclude=BPMName" -redef=col,Dispersion,0 \
	    | sddsmatrixop -pipe -push=$rmFile -add \
	    | sddsxref -pipe=in $rmFile $tmpRoot.bpmNoise -take=BPMName -transfer=para,*
	file copy -force $tmpRoot.bpmNoise $rmFile
	set rmFile $vrmFile
	incr seed 5000
	exec sddsprocess $rmFile -pipe=out "-rpnexpression=$seed srnd" \
	    "-redef=col,%s,grnd $bpmNoise *,select=*,exclude=BPMName" \
	    | sddsmatrixop -pipe -push=$rmFile -add \
	    | sddsxref -pipe=in $rmFile $tmpRoot.bpmNoise -take=BPMName -transfer=para,*
	file copy -force $tmpRoot.bpmNoise $rmFile
	lappend deleteFiles $tmpRoot.bpmNoise
    }
}

#-------------------------------------------------------------------------------------------------------------------------

proc RunOrbitCorrection {args} {

    global workDir deleteFiles
    APSParseArguments {outputFile fileRoot lteFile beamline paramFileList closedOrbit twissRefFile twissRefElement \
			   hcorListOC vcorListOC}

    set rootname $workDir/correctOrbit
    set eleFile $rootname.ele
    
    #------ Make use-correctors-for-steering file:
    exec sddsmakedataset -pipe=out -col=ElementName,type=string -data=[join [concat $hcorListOC $vcorListOC] ,] \
	| sddsprocess -pipe=in $fileRoot.corrOC.param -def=col,ParameterValue,1 -print=col,ElementParameter,STEERING
    lappend deleteFiles $fileRoot.corrOC.param
    
    if $closedOrbit {set mode orbit; set matched 1} else {set mode trajectory; set matched 0}
    if [catch {Fit_GenerateElegantFileFromLTE1 -eleOutputFile $eleFile \
		   -run_setup [list "lattice $lteFile use_beamline $beamline rootname $rootname centroid %s.cen default_order 2"] \
		   -load_parameters [list "filename_list \"$paramFileList\""] \
		   -alter_elements [list "name * type MAXAMP item X_MAX value 0" "name * type MAXAMP item Y_MAX value 0" \
					"name * type *KICK* item STEERING value 0"] \
		   -load_parameters2 [list "filename $fileRoot.corrOC.param"] \
		   -correct [list "mode $mode trajectory_output %s.traj corrector_output %s.corr n_iterations 10 n_xy_cycles 3"] \
		   -closed_orbit [list "output %s.orb"] \
		   -twissOutput [list "matched $matched filename %s.twi reference_file $twissRefFile reference_element $twissRefElement radiation_integrals 1"] \
		   -run_control [list "n_steps 1"] \
		   -bunched_beam [list "n_particles_per_bunch 1"] \
	       } result] {
	return -code error "Fit_GenerateElegantFileFromLTE1: $result"
    }
    
    catch {file delete $eleFile.log}
    if [catch {exec elegant $eleFile > $eleFile.log} result] {
	return -code error "Error running elegant (see $eleFile.log): $result"
    }
    file copy -force $rootname.orb $fileRoot.orb
    lappend deleteFiles $eleFile.log $rootname.traj $eleFile $rootname.cen $rootname.corr $rootname.orb

    exec sddscombine $rootname.corr -pipe=out -merge \
	| sddsconvert -pipe -retain=col,ElementName,ParameterValue,ElementParameter \
	| sddsprocess -pipe=in $outputFile -print=col,ParameterMode,DIFFERENTIAL -print=col,VariableType,OrbitCorrection
}

#-------------------------------------------------------------------------------------------------------------------------

proc RunTuneCorrection {args} {

    global workDir deleteFiles logFile
    APSParseArguments {outputFile fileRoot lteFile beamline paramFileList closedOrbit twissRefFile twissRefElement \
			   knobFile paramFileList0 verbose}

    if [string length $knobFile] {
	if ![file exists $knobFile] {return -code error "Knob file $knobFile does not exist."}
    } else {
	return -code error "Knob file variable is empty."
    }
    set rootname $workDir/correctTunes
    set eleFile $rootname.ele
    set twiFile $rootname.twi

    #------ Get initial tunes:
    if $closedOrbit {
	set twissList [list "matched 1 filename %s.twi"]
    } else {
	set twissList [list "matched 0 filename %s.twi reference_file $twissRefFile reference_element $twissRefElement"]
    }
    if [catch {Fit_GenerateElegantFileFromLTE1 -eleOutputFile $eleFile \
		   -run_setup [list "lattice $lteFile use_beamline $beamline rootname $rootname"] \
		   -load_parameters [list "filename_list \"$paramFileList0\""] \
		   -twiss_output $twissList \
		   -run_control [list "n_steps 1"] \
		   -bunched_beam [list "n_particles_per_bunch 1"] \
	       } result] {
	return -code error "Fit_GenerateElegantFileFromLTE1: $result"
    }
    if [catch {GetTunes -eleFile $eleFile -twiFile $twiFile} tuneList] {
	return -code error "GetTunes: $tuneList"
    }
    lappend deleteFiles $eleFile $twiFile $eleFile.log
    OutputMessage -logFile $logFile -verbose $verbose \
	-text "Model tunes are: Qx=[format %10.5f [lindex $tuneList 0]], Qy=[format %10.5f [lindex $tuneList 1]]"

    #------ Adjust tunes:
    if [catch {AdjustTunes \
		   -lteFile $lteFile \
		   -beamline $beamline \
		   -paramFileList $paramFileList \
		   -knobFile $knobFile \
		   -outputFile $outputFile \
		   -Qx [lindex $tuneList 0] \
		   -Qy [lindex $tuneList 1] \
		   -iterations 10 \
		   -tol 0.01 \
		   -closedOrbit $closedOrbit \
		   -twissRefFile $twissRefFile \
		   -twissRefElement $twissRefElement \
		   -verbose $verbose \
	       } result] {
        return -code error "AdjustTunes: $result"
    }

}
#----------------------------------------------------------------------------------------------------------------------------

proc AdjustTunes {args} {
    global workDir deleteFiles logFile
    APSParseArguments {lteFile beamline paramFileList outputFile Qx Qy knobFile iterations tol \
			   closedOrbit twissRefFile twissRefElement verbose}

    set rootname $workDir/adjustTunes
    set eleFile $rootname.ele
    set localParamFile $rootname.param
    set twiFile $rootname.twi
    lappend deleteFiles $eleFile $localParamFile $eleFile.log $twiFile

    if $closedOrbit {
	set twissList [list "matched 1 filename %s.twi"]
    } else {
	set twissList [list "matched 0 filename %s.twi reference_file $twissRefFile reference_element $twissRefElement"]
    }
    if [catch {Fit_GenerateElegantFileFromLTE1 -eleOutputFile $eleFile \
		   -run_setup [list "lattice $lteFile use_beamline $beamline rootname $rootname default_order 2"] \
		   -load_parameters [list "filename_list \"[concat $paramFileList $localParamFile]\""] \
		   -twiss_output $twissList \
		   -run_control [list "n_steps 1"] \
		   -bunched_beam [list "n_particles_per_bunch 1"] \
	       } result] {
	return -code error "Fit_GenerateElegantFileFromLTE1: $result"
    }

    #------ Getting initial tunes...
    if [catch {MakeParamFile -filename $localParamFile -knobFile $knobFile -xCoeff 0 -yCoeff 0} result] {
        return -code error "MakeParamFile: $result"
    }
    if [catch {GetTunes -eleFile $eleFile -twiFile $twiFile} tuneList] {
        return -code error "GetTunes: $tuneList"
    }
    file copy -force $localParamFile $localParamFile.0
    lappend deleteFiles $localParamFile $localParamFile.0
    set Qx0 [lindex $tuneList 0]
    set Qy0 [lindex $tuneList 1]
    OutputMessage -logFile $logFile -verbose $verbose \
	-text "Initial tunes are: Qx=[format %10.5f $Qx0], Qy=[format %10.5f $Qy0]"
    #------ Getting tune derivatives...
    if [catch {GetTuneDerivatives -eleFile $eleFile -knobFile $knobFile \
		   -paramFile $localParamFile -twiFile $twiFile -verbose $verbose} derivativeList] {
        return -code error "GetTuneDerivatives: $derivativeList"
    }
    set Qx1 [lindex $derivativeList 0]
    set Qy1 [lindex $derivativeList 1]
    set Qx2 [lindex $derivativeList 2]
    set Qy2 [lindex $derivativeList 3]
    #------ Return localParamFile to 0 after derivative calculation.
    if [catch {MakeParamFile -filename $localParamFile -knobFile $knobFile -xCoeff 0 -yCoeff 0} result] {
        return -code error "MakeParamFile: $result"
    }

    #------ Iterations
    OutputMessage -logFile $logFile -verbose $verbose -text "Adjusting tunes..."
    set done 0
    set I 0
    while {$done == 0} {
        set dQx [expr $Qx - $Qx0]
        set dQy [expr $Qy - $Qy0]
        set G1 [expr ($Qy2 * $dQx - $Qx2 * $dQy) / ($Qx1 * $Qy2 - $Qy1 * $Qx2)]
        set G2 [expr ($Qx1 * $dQy - $Qy1 * $dQx) / ($Qx1 * $Qy2 - $Qy1 * $Qx2)]
        if [catch {MakeParamFile -filename $localParamFile.iter -knobFile $knobFile -xCoeff $G1 -yCoeff $G2} result] {
            return -code error "MakeParamFile: $result"
        }
        if [catch {exec sddscombine $localParamFile $localParamFile.iter -pipe=out \
		       | sddsenvelope -pipe -sum=1,ParameterValue -copy=ElementName,ElementParameter,ParameterMode \
		       | sddsconvert -pipe=in $localParamFile.tmp -rename=col,ParameterValueSum=ParameterValue} result] {
	    return -code error "Error updating parameter file during iteration $I ($localParamFile $localParamFile.iter)"
	}
        file copy -force $localParamFile.tmp $localParamFile
        if [catch {GetTunes -eleFile $eleFile -twiFile $twiFile} tuneList] {
            return -code error "GetTunes: $tuneList"
        }
	OutputMessage -logFile $logFile -verbose $verbose -text "Iteration $I: $tuneList"
	set Qxprev $Qx0
	set Qyprev $Qy0
        set Qx0 [lindex $tuneList 0]
        set Qy0 [lindex $tuneList 1]
        if [catch {set dQx1 [expr abs($Qx0 - $Qxprev)]} result] {
	    OutputMessage -logFile $logFile -verbose $verbose \
		-text "Iteration $I, tune X: $result. Using nearest resonance tune."
	    set Qx0 [exec rpnl "$Qxprev 2 * 0.5 + int 2 /"]
	    set dQx1 [expr abs($Qx - $Qx0)]
	}
        if [catch {set dQy1 [expr abs($Qy0 - $Qyprev)]} result] {
	    OutputMessage -logFile $logFile -verbose $verbose \
		-text "Iteration $I, tune Y: $result. Using nearest resonance tune."
	    set Qy0 [exec rpnl "$Qyprev 2 * 0.5 + int 2 /"]
	    set dQy1 [expr abs($Qy - $Qy0)]
	}
	if {($dQx1 < $tol) && ($dQy1 < $tol)} {
	    set done 1
	} else {
	    incr I
	    if {$I > $iterations} {
		OutputMessage -logFile $logFile -verbose $verbose -text "Maximum number of iteration achieved."
		set done 1
	    }
	}
    }
    exec sddsprocess $localParamFile $outputFile -print=col,VariableType,TuneCorrection
#    file copy -force $localParamFile $outputFile
    lappend deleteFiles $localParamFile.tmp $localParamFile.iter

    OutputMessage -logFile $logFile -verbose $verbose \
	-text "Done. Final tunes are: Qx=[format %10.5f [lindex $tuneList 0]], Qy=[format %10.5f [lindex $tuneList 1]]"
}

#-------------------------------------------------------------------------------------------------------------------------

proc GetTuneDerivatives {args} {
    global logFile
    APSParseArguments {eleFile knobFile paramFile twiFile verbose}
    
    OutputMessage -logFile $logFile -verbose $verbose -text "Getting tune derivatives..."
    
    #--- List over non-perturbed tunes, x knob, and y knob:
    set coeff 0.001
    foreach coeffList [list "0 0" "$coeff 0" "0 $coeff"] listName [list tuneList0 tuneList1 tuneList2] {
        if [catch {MakeParamFile -filename $paramFile -knobFile $knobFile \
		       -xCoeff [lindex $coeffList 0] -yCoeff [lindex $coeffList 1]} result] {
            return -code error "MakeParamFile: $result"
        }
        if [catch {GetTunes -eleFile $eleFile -twiFile $twiFile} $listName] {
            return -code error "GetTunes: [set $listName]"
        }
    }
    
    set Qx1 [expr ([lindex $tuneList1 0] - [lindex $tuneList0 0]) / $coeff]
    set Qy1 [expr ([lindex $tuneList1 1] - [lindex $tuneList0 1]) / $coeff]
    set Qx2 [expr ([lindex $tuneList2 0] - [lindex $tuneList0 0]) / $coeff]
    set Qy2 [expr ([lindex $tuneList2 1] - [lindex $tuneList0 1]) / $coeff]
    return [list $Qx1 $Qy1 $Qx2 $Qy2]
}

#-------------------------------------------------------------------------------------------------------------------------

proc GetTunes {args} {
    APSParseArguments {eleFile twiFile}
    if [catch {exec elegant $eleFile > $eleFile.log} result] {
        return -code error "Error running elegant: $result"
    }
    set Qx [exec sdds2stream $twiFile -para=nux]
    set Qy [exec sdds2stream $twiFile -para=nuy]
    return [list $Qx $Qy]
}


#-------------------------------------------------------------------------------------------------------------------------

proc MakeParamFile {args} {
    APSParseArguments {filename knobFile xCoeff yCoeff}
    
    set fraction 0.5
    set tmpRoot /tmp/[APSTmpString]-tuneAdjust
    foreach pageName [list S:Tunex S:Tuney] coeff [list $xCoeff $yCoeff] tmpFile [list $tmpRoot.x $tmpRoot.y] {
	exec sddsprocess $knobFile $tmpFile -match=para,ControlName=$pageName \
	    "-reedit=col,ControlName,%/:CurrentAO//" \
	    "-redef=col,Weight,Weight $coeff * $fraction *"
    }
    exec sddscombine $tmpRoot.x $tmpRoot.y -pipe=out -merge \
	| sddssort -pipe -col=ControlName \
	| sddsbreak -pipe -change=ControlName \
	| sddsprocess -pipe -process=ControlName,first,ElementName -process=Weight,sum,ParameterValue \
	| sddscollapse -pipe \
	| sddsconvert -pipe -retain=col,ElementName,ParameterValue \
	| sddsprocess -pipe=in $filename -print=col,ElementParameter,K1 -print=col,ParameterMode,DIFFERENTIAL
    file delete $tmpRoot.x $tmpRoot.y
}

#-------------------------------------------------------------------------------------------------------------------------
proc ProtectDollarSigns {string} {
    set newString ""
    set stringLength [string length $string]
    for {set i 0} {$i < $stringLength} {incr i} {
	if {[string compare [string range $string $i $i] "$"] == 0} {
	    append newString "\\\$"
	} else {
	    append newString [string range $string $i $i]
	}
    }
    return $newString
}
#-------------------------------------------------------------------------------------------------------------------------


set deleteFiles ""
set seed0 $seed

set verbose1 $verbose
source $definitionFile
set verbose $verbose1

if !$responseOnly {
    array set errorArray $errorList
    set errorVarList [list quadError quadTilt sextDispX sextDispY corCalib bpmGain corTilt bpmTilt bpmNoise bpmAver]
    foreach errorVar $errorVarList {
	set $errorVar $errorArray($errorVar)
    }

    source $elementListFile

    #------ Generating files for errors:
    set elementList [list $quadList $skewList $sextList $sextList $hcorList $hcorList $vcorList $vcorList $xbpmList $xbpmList \
			 $ybpmList $ybpmList]
    set fileList [list $rootname.quad.param $rootname.quadTilt.param \
		      $rootname.sextDispX.param $rootname.sextDispY.param \
		      $rootname.hcor.param $rootname.hcorTilt.param \
		      $rootname.vcor.param $rootname.vcorTilt.param \
		      $rootname.xbpm.param $rootname.xbpmTilt.param \
		      $rootname.ybpm.param $rootname.ybpmTilt.param]
    catch {eval file delete $fileList}
    set deleteFiles [concat $deleteFiles $fileList]
    set errorList [list $quadError $quadTilt $sextDispX $sextDispY $corCalib $corTilt $corCalib $corTilt $bpmGain $bpmTilt \
		       $bpmGain $bpmTilt]
    set pageIDList [list Quad Skew Sext Sext hCorr hCorrTilt vCorr vCorrTilt xBpm xBpmTilt yBpm yBpmTilt]
    set parameterList [list K1 TILT DX DY CALIBRATION TILT CALIBRATION TILT XCALIBRATION TILT YCALIBRATION TILT]
    set parameterModeList [list DIFFERENTIAL DIFFERENTIAL DIFFERENTIAL DIFFERENTIAL FRACTIONAL DIFFERENTIAL FRACTIONAL DIFFERENTIAL \
			       FRACTIONAL DIFFERENTIAL FRACTIONAL DIFFERENTIAL]

    set gLimit 2.0
    set fileListFinal ""
    foreach elements $elementList filename $fileList error $errorList parameter $parameterList pageID $pageIDList \
	parameterMode $parameterModeList {
	    if [llength $elements] {
		incr seed 5
		exec sddsmakedataset -pipe=out -col=ElementName,type=string -data=[join $elements ,] \
		    | sddsprocess -pipe=in $filename "-rpnexpression=$seed srnd" "-def=col,ParameterValue,$gLimit grndl $error *" \
		    -print=col,ElementParameter,$parameter -print=col,ParameterMode,DIFFERENTIAL -print=col,VariableType,$pageID \
		    -redef=para,Error,$error
		lappend fileListFinal $filename
	    }
	}

    #------ This is for making sextupole displacements by girders for NSLSII:
    if {[string compare $machineName NSLS2] == 0} {set sextDispByGirders 1} else {set sextDispByGirders 0}
    if $sextDispByGirders {
	incr seed 5
	exec sddsprocess $rootname.sextDispX.param -pipe=out "-edit=col,GirderStr,ElementName,zG d S@C@ K" \
	    | sddsbreak -pipe -change=GirderStr \
	    | sddsprocess -pipe "-rpnexpression=$seed srnd" "-def=param,ParameterValueParam,$gLimit grndl $sextDispX *" \
	    -redef=col,ParameterValue,ParameterValueParam \
	    | sddscombine -pipe=in $rootname.sextDispX.param.tmp -merge
	file copy -force $rootname.sextDispX.param.tmp $rootname.sextDispX.param
	incr seed 5
	exec sddsprocess $rootname.sextDispY.param -pipe=out "-edit=col,GirderStr,ElementName,zG d S@C@ K" \
	    | sddsbreak -pipe -change=GirderStr \
	    | sddsprocess -pipe "-rpnexpression=$seed srnd" "-def=param,ParameterValueParam,$gLimit grndl $sextDispY *" \
	    -redef=col,ParameterValue,ParameterValueParam \
	    | sddscombine -pipe=in $rootname.sextDispY.param.tmp -merge
	file copy -force $rootname.sextDispY.param.tmp $rootname.sextDispY.param
	lappend deleteFiles $rootname.sextDispX.param.tmp $rootname.sextDispY.param.tmp
    }

    #------ Combine sextupole displacement files:
    if [llength $sextList] {
	exec sddscombine $rootname.sextDispX.param $rootname.sextDispY.param $rootname.sextDisp.param -merge -overWrite
	lappend deleteFiles $rootname.sextDisp.param
    }

    #------ Add Dispersion line to hcor files:
    if [llength $hcorList ] {
	exec sddsmakedataset -pipe=out -col=ElementName,type=string -data=Dispersion \
	    | sddsprocess -pipe=in $tmpRoot.disp1 -def=col,ParameterValue,0.0 \
	    -print=col,ElementParameter,CALIBRATION -print=col,ParameterMode,DIFFERENTIAL -print=col,VariableType,hCorr
	exec sddscombine $rootname.hcor.param $tmpRoot.disp1 $tmpRoot.disp2 -merge -overWrite
	file copy -force $tmpRoot.disp2 $rootname.hcor.param
	exec sddsmakedataset -pipe=out -col=ElementName,type=string -data=Dispersion \
	    | sddsprocess -pipe=in $tmpRoot.disp3 -def=col,ParameterValue,0.0 \
	    -print=col,ElementParameter,TILT -print=col,ParameterMode,DIFFERENTIAL -print=col,VariableType,hCorrTilt
	exec sddscombine $rootname.hcorTilt.param $tmpRoot.disp3 $tmpRoot.disp4 -merge -overWrite
	file copy -force $tmpRoot.disp4 $rootname.hcorTilt.param
	lappend deleteFiles $tmpRoot.disp1 $tmpRoot.disp2 $tmpRoot.disp3 $tmpRoot.disp4
    }

    #------ Adding average BPM error:
    if {$bpmAver != 0} {
	if [llength $xbpmList] {
	    exec sddsprocess -nowarning $rootname.xbpm.param "-redef=col,ParameterValue,ParameterValue $bpmAver +"
	    lappend deleteFiles $rootname.xbpm.param~
	}
	if [llength $ybpmList] {
	    exec sddsprocess -nowarning $rootname.ybpm.param "-redef=col,ParameterValue,ParameterValue $bpmAver +"
	    lappend deleteFiles $rootname.ybpm.param~
	}
	
    }

    #------ Removing average bpm gain error:
    if $removeAverageBpmError {
	if [llength $xbpmList] {
	    exec sddsprocess -nowarning $rootname.xbpm.param -process=ParameterValue,average,Aver \
		"-redef=col,ParameterValue,ParameterValue Aver -"
	    lappend deleteFiles $rootname.xbpm.param~
	}
	if [llength $ybpmList] {
	    exec sddsprocess -nowarning $rootname.ybpm.param -process=ParameterValue,average,Aver \
		"-redef=col,ParameterValue,ParameterValue Aver -"
	    lappend deleteFiles $rootname.ybpm.param~
	}
    }

    eval exec sddscombine $fileListFinal $rootname.errors.param -merge -overWrite
    set finalErrorFileList $rootname.errors.param

    #------ Running elegant for orbit correction:
    if $correctOrbit {
	OutputMessage -logFile $logFile -verbose $verbose -text "Correcting orbit..."
	set localParamFileList $paramFileList
	foreach filename [list $rootname.quad.param $rootname.quadTilt.param $rootname.sextDisp.param] {
	    if [file exists $filename] {set localParamFileList [concat $localParamFileList $filename]}
	}
	if [catch {RunOrbitCorrection -outputFile $rootname.orbCor.param \
		       -fileRoot $rootname -lteFile $lteFile -beamline $beamline -paramFileList $localParamFileList \
		       -closedOrbit $closedOrbit -twissRefFile $twissRefFile -twissRefElement $twissRefElement \
		       -hcorListOC $hcorListOC -vcorListOC $vcorListOC} result] {
	    return -code error "RunOrbitCorrection: $result"
	}
	set finalErrorFileList [concat $finalErrorFileList $rootname.orbCor.param]
	lappend deleteFiles $rootname.orbCor.param
    }

    #------ Correcting tunes:
    if $correctTunes {
	OutputMessage -logFile $logFile -verbose $verbose -text "Correcting tunes..."
	set localParamFileList $paramFileList
	foreach filename [list $rootname.quad.param $rootname.quadTilt.param $rootname.sextDisp.param] {
	    if [file exists $filename] {set localParamFileList [concat $localParamFileList $filename]}
	}
	if [catch {RunTuneCorrection -outputFile $rootname.tuneCor.param \
		       -fileRoot $rootname -lteFile $lteFile -beamline $beamline -paramFileList $localParamFileList \
		       -closedOrbit $closedOrbit -twissRefFile $twissRefFile -twissRefElement $twissRefElement \
		       -knobFile $knobFile -paramFileList0 $paramFileList -verbose $verbose} result] {
	    return -code error "RunTuneCorrection: $result"
	}
	set finalErrorFileList [concat $finalErrorFileList $rootname.tuneCor.param]
	lappend deleteFiles $rootname.tuneCor.param
    }

    #------ Making final error file with all errors and orbit correction 
    #------ (NOTE: elements can appear several times in the final file, elegant reads parameter file row-by-row):
    set parDefString ""
    foreach errorType $errorVarList {
	append parDefString " -def=para,$errorType,[set $errorType] "
    }
    if [catch {eval exec sddscombine $finalErrorFileList -pipe=out -merge \
		   | sddsprocess -pipe=in $rootname.errors.param.tmp \
		   -print=para,Rootname,$rootname \
		   -def=para,Seed,$seed0 \
		   -def=para,RemoveAverageBpmError,$removeAverageBpmError \
		   -def=para,CorrectTunes,$correctTunes \
		   -def=para,CorrectOrbit,$correctOrbit $parDefString} result] {
	return -code error "Error combining final parameter file (finalErrorFileList: $finalErrorFileList): $result"
    } else {
	file copy -force $rootname.errors.param.tmp $rootname.errors.param
	lappend deleteFiles $rootname.errors.param.tmp
    }

} else {
    #------ If responseOnly, make required files from the existing error file:
    set extList [list hcor vcor xbpm xbpmTilt ybpm ybpmTilt]
    set pidList [list hCorr vCorr xBpm xBpmTilt yBpm yBpmTilt]
    foreach ext $extList pid $pidList {
	exec sddsprocess $rootname.errors.param $rootname.$ext.param -nowarning -match=col,VariableType=$pid
	lappend deleteFiles $rootname.$ext.param
    }
    set hcorList [join [exec sdds2stream $rootname.hcor.param -col=ElementName] ]
    set hcorList [lreplace $hcorList [lsearch -exact $hcorList Dispersion] [lsearch -exact $hcorList Dispersion]]
    set vcorList [join [exec sdds2stream $rootname.vcor.param -col=ElementName] ]
    array set errorArray $errorList
    set bpmNoise $errorArray(bpmNoise)
    set finalErrorFileList $rootname.errors.param
}

#------ Calculating response matrix:

OutputMessage -logFile $logFile -verbose $verbose -text "Calculating response matrices..."

#------ Make unique BPM names:
set removePlaneSuffix 0
if $makeBpmNamesUnique {
    set rawLteFile $lteFile
    if {[string first uniqueBpms $lteFile] != -1} {
	puts stdout "GOTCHA -- uniqueBpms.uniqueBpms -- GOTCHA"
	puts stdout "GOTCHA -- uniqueBpms.uniqueBpms -- GOTCHA"
	puts stdout "GOTCHA -- uniqueBpms.uniqueBpms -- GOTCHA"
    }
    set lteFile $workDir/[file tail $lteFile].uniqueBpms
    if [catch {Fit_MakeBpmNamesUnique -inputLTE $rawLteFile -outputLTE $lteFile} result] {
	return -code error "Fit_MakeBpmNamesUnique: $result"
    }
    set removePlaneSuffix 1
}

set verbose1 $verbose
source $definitionFile
set verbose $verbose1

set beamlineName $beamline
set latticeParamFileList [concat $paramFileList $rootname.errors.param]

set hrmFile $rootname.hrm.calc
set vrmFile $rootname.vrm.calc
set hrmFileIdeal $rootname.hrm.ideal
set vrmFileIdeal $rootname.vrm.ideal
set hCorrList $hcorList
set vCorrList $vcorList
set kickX $kick
set kickY $kick
set coupledMatrix 2
set acceleratorCode elegant
set optimFile dummy
set directCalc $directRMCalc
set fitDispersion 1

set useQsub $useQsubShort
set numberOfQsubTasks $numberOfQsubTasksShort
set waitTime $waitTimeShort
set waitInterval $waitIntervalShort
set qsubCommand $qsubCommandShort
set queueSystemName $queueSystemNameShort
set submissionPause $submissionPauseShort
set qsubRespProcCommand $qsubRespProcCommandShort
foreach localParamFileList [list $paramFileList $latticeParamFileList] \
    localHrmFile [list $hrmFileIdeal $hrmFile] \
    localVrmFile [list $vrmFileIdeal $vrmFile] \
    localTwiFile [list $twiFile.ideal $twiFile] {
	set command "$locoBinDir/calculateResponseMatrix \
               -runMode getResponseMatrix \
	       -acceleratorCode $acceleratorCode \
	       -lteFile $lteFile \
	       -beamlineName $beamlineName \
	       -latticeParamFileList \"$localParamFileList\" \
	       -optimFile $optimFile \
	       -hrmFile $localHrmFile \
	       -vrmFile $localVrmFile \
	       -hCorrList \"$hCorrList\" \
	       -vCorrList \"$vCorrList\" \
	       -workDir $workDir \
	       -useQsub $useQsub \
	       -bRho $bRho \
	       -twiFile $localTwiFile \
	       -twissRefFile $twissRefFile \
	       -twissRefElement $twissRefElement \
	       -dispFitWeight $dispFitWeight \
	       -directCalc $directCalc \
	       -kickX $kickX \
	       -kickY $kickY \
	       -useKickFiles $useKickFiles \
	       -kickFileX $kickFileX \
	       -kickFileY $kickFileY \
	       -fixedOrbitLength $fixedOrbitLength \
	       -fitDispersion $fitDispersion \
	       -dispColumn $dispColumn \
	       -optimNonlin $optimNonlin \
	       -coupledMatrix $coupledMatrix \
	       -closedOrbit $closedOrbit \
	       -useDoubleOrbits $useDoubleOrbits \
	       -locoSearchString $locoSearchString \
	       -numberOfQsubTasks $numberOfQsubTasks \
	       -waitTime $waitTime \
	       -waitInterval $waitInterval \
	       -qsubCommand \"[ProtectDollarSigns $qsubCommand]\" \
	       -queueSystemName $queueSystemName \
	       -submissionPause $submissionPause \
	       -qsubRespProcCommand \"[ProtectDollarSigns $qsubRespProcCommand]\""
	if {$verbose == 2} {puts stdout $command}
	if [catch {eval exec $command >@ stdout} result] {
	    return -code error "calculateResponseMatrix error: $result"
	}
	if $verbose {
	    set tuneList [exec sdds2stream $localTwiFile -para=nux,nuy]
	    puts stdout "Tunes: nux= [format %7.3f [lindex $tuneList 0]]; nuy= [format %7.3f [lindex $tuneList 1]]."
	}
	lappend deleteFiles $localHrmFile.XRM $localVrmFile.XRM
    }
file copy -force $twiFile $outputTwissFile
file copy -force $twiFile.ideal $outputTwissFile.ideal
lappend deleteFiles $twiFile $twiFile.ideal

#------ Beam moments calculation:
if $calculateBeamMoments {
    OutputMessage -logFile $logFile -verbose $verbose -text "Calculating beam moments..."
    if [catch {CalculateMoments -lteFile $lteFile -paramFileList $latticeParamFileList -rootname $rootname \
		   -rfBeamlineName $rfBeamlineName} result] {
	return -code error "CalculateMoments: $result"
    }
}

OutputMessage -logFile $logFile -verbose $verbose -text "Postprocessing response matrix files..."

#------ Corrector calibration is already applied through $latticeParamFileList during calculation of matrices

#------ Apply calibration to bpm noise:
#------ Output file of response calculations is (X1-X2)/kick/2. I use sqrt(2) here
set bpmNoise1 [expr $bpmNoise / $kick * 1.414]
if [catch {ApplyBPMCorrections -hrmFile $hrmFile -hrmXFile $hrmFile.XRM -vrmFile $vrmFile -vrmXFile $vrmFile.XRM \
	       -elementFileRoot $rootname -coupledMatrix 2 -bpmNoise $bpmNoise1 -seed $seed} result] {
    return -code error "ApplyBPMCorrections: $result"
}

#------ Transforming into measured files format (splitting, transposing, and calibrating):
if $transform2measuredFormat {
    #------ Doing response files:
    exec sddsconvert $hrmFile $hrmFile.tmp -del=col,$dispColumn
    lappend deleteFiles $hrmFile.tmp
    set dirName [file dirname $rootname]
    set fileRoot [file tail $rootname]
    foreach \
	sourceFile [list $hrmFile.tmp $hrmFile.tmp $vrmFile $vrmFile] \
	rmFile [list $dirName/h$fileRoot.hrm $dirName/h$fileRoot.vrm $dirName/v$fileRoot.hrm $dirName/v$fileRoot.vrm] \
	keepPage [list 1 2 1 2] \
	kick [list $kickX $kickX $kickY $kickY] \
	calibFactor [list $hCalibFactor $hCalibFactor $vCalibFactor $vCalibFactor] {
	    set kick 1.0
	    if $removePlaneSuffix {
		exec sddsconvert $sourceFile -pipe=out -keepPage=$keepPage \
		    | sddsprocess -pipe "-redef=col,%s,%s $calibFactor * ,select=*,exclude=BPMName" \
		    "-reedit=col,BPMName,e 1b 1d" -define=para,MeasuredFormat,$transform2measuredFormat,type=long \
		    | sddstranspose -pipe=in $rmFile -newColumn=BPMName -oldColumn=Corrector
	    } else {
		exec sddsconvert $sourceFile -pipe=out -keepPage=$keepPage \
		    | sddsprocess -pipe "-redef=col,%s,%s $calibFactor * ,select=*,exclude=BPMName" \
		    -define=para,MeasuredFormat,$transform2measuredFormat,type=long \
		    | sddstranspose -pipe=in $rmFile -newColumn=BPMName -oldColumn=Corrector
	    }
	}
    
    #------ Doing dispersion file:
    switch -exact $machineName {
	APS {
	    exec sddsmakedataset $tmpRoot.dispCol -col=DispColumn,type=string -data=xDispersion,yDispersion
	    lappend deleteFiles $tmpRoot.dispCol
	    exec sddsconvert $hrmFile -pipe=out -retain=col,BPMName,$dispColumn \
		| sddstranspose -pipe -newColumn=BPMName -oldColumn=Dispersion \
		| sddscombine -pipe -merge \
		| sddsxref -pipe $tmpRoot.dispCol -take=DispColumn \
		| sddstranspose -pipe -newColumn=DispColumn -oldColumn=BPMName \
		| sddsprocess -pipe "-redef=col,%s,%s $dispFitWeight / $dispCalibFactor /,select=*Dispersion" \
		| sddsconvert -pipe=in $rootname.slopes -del=col,Dispersion -rename=col,BPMName=Rootname -del=para,*
	}
	TAA {
	    exec sddsconvert $hrmFile -pipe=out -retain=col,BPMName,$dispColumn \
		| sddsprocess -pipe=in $rootname.slopes "-redef=col,$dispColumn,$dispColumn $dispFitWeight / $dispCalibFactor /"
	}
	default {return -code error "Machine $machineName not known during dispersion file creation..."}
    }
    if $removePlaneSuffix {
	exec sddsprocess $rootname.slopes -nowarning "-reedit=col,Rootname,e 1b 1d"
	lappend deleteFiles $rootname.slopes~
    }
} else {
    exec sddsprocess $hrmFile $hrmFile.mf -define=para,MeasuredFormat,$transform2measuredFormat,type=long
    exec sddsprocess $vrmFile $vrmFile.mf -define=para,MeasuredFormat,$transform2measuredFormat,type=long
    file copy -force $hrmFile.mf $hrmFile
    file copy -force $vrmFile.mf $vrmFile
    lappend deleteFiles $hrmFile.mf $vrmFile.mf
}

OutputMessage -logFile $logFile -verbose $verbose -text "Generating measurements: done."

eval file delete $deleteFiles

exit

/home/oxygen/SAJAEV/LOCO-FNAL/generateResponseWithErrors  -machineName APS  -lteFile /scratch/sajaev/CONFIG/021/aps.lte  -makeBpmNamesUnique 1  -beamline RING  -paramFileList "/scratch/sajaev/CONFIG/021/tuneAdjust.param /scratch/sajaev/CONFIG/021/sext.param"  -errorList "quadError 0.001 quadTilt 0.0005 sextDispX 0.0005 sextDispY 0.0005 corCalib 0.02 bpmGain 0.05 corTilt 0.001 bpmTilt 0.01 bpmNoise 1e-6 bpmAver 0"  -elementListFile /scratch/sajaev/jobs/jobs/betaTest.noiseElements.tcl  -rootname /scratch/sajaev/jobs/jobs/0/betaTest  -seed 123456789  -kick 2.65e-5  -removeAverageBpmError 0  -correctOrbit 1  -correctTunes 1  -knobFile /scratch/sajaev/CONFIG/021/tune.cokn  -workDir /scratch/sajaev/jobs/jobs/0  -transform2measuredFormat 0  -definitionFile /scratch/sajaev/jobs/jobs/initialDefinitions.tcl  -outputTwissFile /scratch/sajaev/jobs/jobs/0/beta0.twi  -logFile /scratch/sajaev/jobs/jobs/0/betaTest.log  -verbose 1