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

# $Log: not supported by cvs2svn $
# Revision 1.14  2011/07/01 13:55:08  shang
# added missing "exec" before "ln -s"
#
# Revision 1.13  2011/06/30 20:18:19  shang
# added new table generation feature.
#
# Revision 1.12  2008/09/22 16:02:32  soliday
# Fixed a problem with the TEST VALUES button when it was clicked before the
# RUN button.
#
# Revision 1.11  2008/04/08 22:16:39  shang
# modified the description context to avoid confusing.
#
# Revision 1.10  2008/04/08 21:07:28  shang
# changed the tube amplifier pv back
#
# Revision 1.9  2008/04/08 20:37:41  shang
# modified due to the pv name change of tube amplifier.
#
# Revision 1.8  2008/03/24 19:57:33  shang
# removed callback of RUN feedforward so that user can abort the feedforward through runcontrol medm screen.
#
# Revision 1.7  2007/03/06 16:42:23  shang
# the feedforward now automatically starts and switches between tube 1 and tube 2 as the tube switches.
#
# Revision 1.6  2007/02/13 21:53:09  emery
# Detects type of RF1 amplifier.
#
# Revision 1.5  2006/07/18 16:52:15  flood
# Added test values button
#
# Revision 1.4  2006/04/12 16:06:58  soliday
# Updated the run control PV name from a temporary name to a permanent one
# per CY's request.
#
# Revision 1.3  2006/03/24 19:58:26  shang
# moved the files into CVS
#
# Revision 1.2  2005/06/20 21:44:26  shang
# changed the default input and test file to the newly created files.
#
# Revision 1.1  2005/03/15 18:16:50  shang
# first version
#
# copied from quickMonitor script and made some changes for Feedforward
#

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.15 $ \$Author: shang $"

APSApplication . -name PARRF12TunerFeedforward -version $CVSRevisionAuthor \
  -overview {This is the PARRF12TunerFeedforward utility.  It provides a simple interface to the sddsfeedforward program.}

set FFDir /home/helios/oagData/par/feedforwardConfig/parTunerFeedforward
set mainStatus "ready."
set Interval 0.05

#set runControlPV APS:RunControlSlot4RC
set runControlPV PAR:RF12:TunerFeedFwdRC
set runControlDesc "par harmonic tuner feedforward"
set runControlPingTimeout 30

proc SetMainStatus {text} {
    global mainStatus
    set mainStatus $text
    update
}

APSScrolledStatus .status -parent .userFrame -textVariable mainStatus -width 90

set width 60
APSLabeledEntry .runcontrol -parent .userFrame -label "Run control pv:" \
    -textVariable runControlPV -width $width \
    -contextHelp "enter the run control pv for running feedforward."
APSLabeledEntry .desc -parent .userFrame -label "Run control description:" \
    -textVariable runControlDesc -width $width \
    -contextHelp "run control description."
APSLabeledEntry .time -parent .userFrame -label "Run control ping timeout (s):" \
    -textVariable runControlPingTimeout -width $width 
APSLabeledEntry .interval -parent .userFrame -label "Interval (s): " \
    -textVariable Interval -width $width \
    -contextHelp "Enter the time between samples in seconds in this field."
if [pv linkw tubeAmplifier PAR:Fnd:SystemSelect] {
    puts stderr "$errorCode"
    exit
}
if [pv umon tubeAmplifier 30] {
    puts stderr "$errorCode"
    exit
}
if [pv linkw rf12Amplifier PAR:Har:SystemSelect] {
    puts stderr "$errorCode"
    exit
}
if [pv umon rf12Amplifier 30] {
    puts stderr "$errorCode"
    exit
}

if {[regexp {\#1} $tubeAmplifier]} {
    set tube1 1
} elseif [regexp {\#2} $tubeAmplifier] {
    set tube1 2
} else {
    SetMainStatus "Invalid tube amplifier: $tubeAmplifier"
    exit
}
if {[regexp {\#1} $rf12Amplifier]} {
    set tube2 1
} elseif [regexp {\#2} $rf12Amplifier] {
    set tube2 2
} else {
    SetMainStatus "Invalid RF12 harmonic amplifier: $rf12Amplifier"
    exit
}
set filename  parRFFeedForwardFund${tube1}Harm${tube2}.sdds
cd $FFDir
set oldFile [file readlink $filename]
if {[file tail $oldFile]=="parRFFeedForwardFund${tube1}Harm${tube2}.newTable"} {
    SetMainStatus "FF was linked to new table, restore the FF table to last installed."
    set file [lindex [lsort [glob [file root ${filename}].?????]] end]
    exec rm $filename
    exec ln -s $file $filename
    SetMainStatus "done"
}

set runControlDesc "Par harmonic tuner feedforward"

APSFrame .f1 -parent .userFrame -label "" -packOption "-side top"
.userFrame.f1.frame configure -bd 0
set w1 .userFrame.f1.frame
APSLabeledOutput .tube -parent $w1 -label "Fundamental Amplifer:" \
    -textVariable tubeAmplifier  -width $width
APSLabeledOutput .tube1 -parent $w1 -label "RF12 harmonic Amplifer:" \
    -textVariable rf12Amplifier  -width $width

set LLRFtype analogLLRF
APSRadioButtonFrame .radio -parent $w1 -label "LLRF type:" -buttonList {analogLLRF digitalLLRF} \
    -valueList {analogLLRF digitalLLRF} -orientation horizontal -commandList {Relink Relink} \
    -variable LLRFtype
APSButton .run -parent $w1 -text RUN -command RunFeedforward \
  -contextHelp "start tuner feedforward process."
APSButton .stop -parent $w1 -text "STOP" -command "AbortFeedforward" \
  -contextHelp "abort tuner feedforward process"
APSButton .info -parent $w1 -text "INFO" -command "FeedforwardInfo" \
  -contextHelp "bring up run control screen for feedforward"

APSButton .testvalues -parent $w1 -text "TEST VALUES" -command " APSControlLawTestValuesButton" \
  -contextHelp "List test values, their status and limits"


APSButton .plot -parent $w1 -text "Plot tunerFF table" -command PlotFFTable \
    -contextHelp "Plot the tunerFF table in two pages."
APSFrame .f2 -parent .userFrame -label "" -packOption "-side top"
set w2 .userFrame.f2.frame
$w2 configure -bd 0

APSButton .enable -parent $w2 -text "Enable/Disable" -command "EnableDisableNewFFButtons" \
    -contextHelp "Enable/Disable making new feedforward table.  Only used by machine managers."
APSButton .tran -parent $w2 -text "Transfer RF Phase Reference" -command "TransferRFPhase -install 1" \
    -contextHelp "Reset PV test values for RF1 and RF12 phase reference. Used after switching amplifiers."
APSButton .gen -parent $w2 -text "Make New  FF" -command "CreateNewTable" \
    -contextHelp "Make a new feedforward table based on present settings of LIST phase and RF12 tuner setpoint."
APSButton .install -parent $w2 -text "Install New FF" -command "InstallNewTable" \
    -contextHelp "Install the new feedforward table."
APSButton .undo -parent $w2 -text "Undo New FF" -command "UndoNewTable" \
			      -contextHelp "relink the FF table to previous table." \
    -contextHelp "Un-install the last installed new table created during current session."
APSDisableButton $w2.tran.button
APSDisableButton $w2.gen.button
APSDisableButton $w2.install.button
APSDisableButton $w2.undo.button
proc EnableDisableNewFFButtons {} {
    if [catch {.userFrame.f2.frame.gen.button cget -state} state] {
	return -code error "Error in getting enable/disable state: $state"
    }
    set enable 0
    if [string compare $state disabled]==0 {
	set enable 1
    }
    if $enable {
	APSEnableButton .userFrame.f2.frame.gen.button
	APSEnableButton .userFrame.f2.frame.install.button
	APSEnableButton .userFrame.f2.frame.undo.button
	APSEnableButton .userFrame.f2.frame.tran.button
    } else {
	APSDisableButton .userFrame.f2.frame.gen.button
	APSDisableButton .userFrame.f2.frame.install.button
	APSDisableButton .userFrame.f2.frame.undo.button
	APSDisableButton .userFrame.f2.frame.tran.button
    }
}

proc GenFFTable {args} {
    set inputFile ""
    set outputFile ""
    set tube1 ""
    set tube2 ""
    APSParseArguments {inputFile outputFile tube1 tube2}
    global FFDir LLRFtype
    if ![string length $tube1] {
        return -code error "GenFFTable: tube1 not provided!"
    }
    if ![string length $tube2] {
        return -code error "GenFFTable: tube2 not provided!"
    }
    set tmpRoot /tmp/[APSTmpString]
    set readback [exec sdds2stream -par=ReadbackName $inputFile]
    set actuator [exec sdds2stream -par=ActuatorName $inputFile]
    set testfile $FFDir/$LLRFtype/feedforwardTestFund${tube1}Harm${tube2}
    
    if [catch {exec cavget -list=$readback -pend=10} readbackVal] {
	return -code error "Error in reading $readback: $readbackVal"
    }
    if [catch {exec cavget -list=$actuator -pend=10} actuatorVal] {
	return -code error "Error in reading $readback: $readbackVal"
    }
    puts "$readback $readbackVal; actuator $actuator  $actuatorVal"
    set min [exec sddsprocess $testfile -match=col,ControlName=$readback -pipe=out | sdds2stream -pipe -col=MinimumValue]
    set max [exec sddsprocess $testfile -match=col,ControlName=$readback -pipe=out | sdds2stream -pipe -col=MaximumValue]

    if {$readbackVal<$min || $readbackVal>$max} {
	return -code error "The current of $readback ($readbackVal) is out of range ($min - $max): new table not generated."
    }
    if [catch {exec sddsmakedataset -col=ReadbackValue,type=double -data=$readbackVal \
		   -col=ActuatorValue,type=double -data=$actuatorVal $tmpRoot.1} result] {
	return -code error "Error in making tuner data1: $result"
    }
    if [catch {exec sddsprocess $inputFile -filter=col,ReadbackValue,0,$readbackVal -pipe=out -nowarnings \
		   | sddsprocess -pipe=in $tmpRoot.a1 -clip=0,1 -nowarnings
	exec sddsprocess $inputFile -filter=col,ReadbackValue,$readbackVal,100 -pipe=out -nowarnings \
		   | sddsprocess -pipe=in $tmpRoot.a2 -clip=1,0 -nowarnings 
	exec sddscombine $tmpRoot.a1 $tmpRoot.a2 $tmpRoot.1 -merge -pipe=out \
		   | sddssort -pipe -col=ReadbackValue \
		   | sddsinterp -pipe -col=ReadbackValue,ActuatorValue -filevalues=$inputFile,col=ReadbackValue  \
		   | sddsxref -pipe=in $inputFile -leave=* -transfer=par,* $outputFile } result] {
	return -code error "Error in making new tuner FF table: $result"
    }
    
}

proc UndoNewTable {args} {
    global FFDir  tubeAmplifier  rf12Amplifier LLRFtype
    
    if {[regexp {\#1} $tubeAmplifier]} {
	set tube1 1
    } elseif [regexp {\#2} $tubeAmplifier] {
	set tube1 2
    } else {
	SetMainStatus "Invalid tube amplifier: $tubeAmplifier"
	return
    }
    if {[regexp {\#1} $rf12Amplifier]} {
	set tube2 1
    } elseif [regexp {\#2} $rf12Amplifier] {
	set tube2 2
    } else {
	SetMainStatus "Invalid RF12 harmonic amplifier: $rf12Amplifier"
	return
    }
    set filename  parRFFeedForwardFund${tube1}Harm${tube2}.sdds
    set oldDir [pwd]
    cd $FFDir/$LLRFtype
    set oldfile [file readlink $filename]
    if [regexp {newTable} $oldfile] {
	set lastFile [lindex [lsort [glob [file root $filename].?????]] end]
	exec rm $filename
	exec ln -s $lastFile $filename
	 SetMainStatus "$filename was moved back to $lastFile"
    } else {
	SetMainStatus "$filename is not linked to new table, no action is done."
    }
    cd $oldDir
    return
}
proc CreateNewTable {args} {
    set filename ""
    set install 1
    APSParseArguments {filename install}
    global FFDir  tubeAmplifier  rf12Amplifier LLRFtype
    
    if ![string length $filename] {
	if {[regexp {\#1} $tubeAmplifier]} {
	    set tube1 1
	} elseif [regexp {\#2} $tubeAmplifier] {
	    set tube1 2
	} else {
	    SetMainStatus "Invalid tube amplifier: $tubeAmplifier"
	    return
	}
	if {[regexp {\#1} $rf12Amplifier]} {
	    set tube2 1
	} elseif [regexp {\#2} $rf12Amplifier] {
	    set tube2 2
	} else {
	    SetMainStatus "Invalid RF12 harmonic amplifier: $rf12Amplifier"
	    return
	}
	set filename  $LLRFtype/parRFFeedForwardFund${tube1}Harm${tube2}.sdds
    }
    SetMainStatus "Generating new table for $filename (Fundamental-$tubeAmplifier,  RF12 harmonic - $rf12Amplifier)"
    set oldDir [pwd]
    cd $FFDir/$LLRFtype
    set oldFile [file readlink $filename]
    if [regexp {newTable} $oldFile] {
	return -code error "New table is already generated and being running."
    }
    set newTable [file root $filename].newTable
   # set newFile [APSNextGenerationedName -name $oldFile -newFile 1 -separator .]
   # puts $newFile
    set tmpRoot /tmp/[APSTmpString]
    if [catch {exec sddssplit $filename -rootname=$tmpRoot -digits=3} result] {
	return -code error $result
    }
    if [catch {GenFFTable -inputFile ${tmpRoot}001.sdds -outputFile $tmpRoot.a -tube1 $tube1 -tube2 $tube2} result] {
	return -code error $result
    }
    if [catch {GenFFTable -inputFile ${tmpRoot}002.sdds -outputFile $tmpRoot.b  -tube1 $tube1 -tube2 $tube2} result] {
	return -code error $result
    }
    if [catch {exec sddscombine $tmpRoot.a $tmpRoot.b $newTable -overwrite} result] {
	return -code error "Error in generating new FF table: $result"
    }
    exec sddsplot -split=page -topline=@Description -group=page -sep=page -grap=sym,vary=sub,connect=sub,scale=2 \
	-xlabel=@ReadbackName -ylabel=@ActuatorName \
	-col=ReadbackValue,ActuatorValue $FFDir/$newTable "-leg=spec=new table" \
	-col=ReadbackValue,ActuatorValue $FFDir/$oldFile "-leg=spec=reference" &
   
    exec rm $filename
    exec ln -s $newTable $filename
    
    SetMainStatus "done."
    cd $oldDir
    
    return
}

proc InstallNewTable {args} {
    global FFDir  tubeAmplifier  rf12Amplifier LLRFtype
    
    if {[regexp {\#1} $tubeAmplifier]} {
	set tube1 1
    } elseif [regexp {\#2} $tubeAmplifier] {
	set tube1 2
    } else {
	SetMainStatus "Invalid tube amplifier: $tubeAmplifier"
	return
    }
    if {[regexp {\#1} $rf12Amplifier]} {
	set tube2 1
    } elseif [regexp {\#2} $rf12Amplifier] {
	set tube2 2
    } else {
	SetMainStatus "Invalid RF12 harmonic amplifier: $rf12Amplifier"
	return
    }
    set filename  parRFFeedForwardFund${tube1}Harm${tube2}.sdds
    set newTable [file root $filename].newTable
    cd $FFDir/$LLRFtype
    set oldFile [file readlink $filename]
    set install 1
    if ![regexp {newTable} $oldFile] {
	if [APSYesNoPopUp "newTable is not being running, it could be generated before, do you still want to install it?"] {
	    set install 1
	} else {
	    set install 0
	}
    }
    if $install {
	SetMainStatus "Install the new table..."
	set newFile [APSNextGenerationedName -name [file root $filename].00001 -newFile 1 -separator .]
	exec cp $newTable $newFile
	exec rm $filename
	exec ln -s $newFile $filename
	SetMainStatus "done."
    }
    cd $oldDir
}

proc PlotFFTable {args} {
     global tubeAmplifier rf12Amplifier FFDir LLRFtype 
    if {[regexp {\#1} $tubeAmplifier]} {
	set tube1 1
    } elseif [regexp {\#2} $tubeAmplifier] {
	set tube1 2
    } else {
	SetMainStatus "Invalid tube amplifier: $tubeAmplifier"
	return
    }
    if {[regexp {\#1} $rf12Amplifier]} {
	set tube2 1
    } elseif [regexp {\#2} $rf12Amplifier] {
	set tube2 2
    } else {
	SetMainStatus "Invalid RF12 harmonic amplifier: $rf12Amplifier"
	return
    }
    set oldDir [pwd]
    cd $FFDir/$LLRFtype/Harm$tube2
    set file  parRFFeedForwardFund${tube1}Harm${tube2}.sdds
    set linkFile [file readlink $file]
    set pars [exec sddsquery -par $file] 
    if [lsearch $pars "Description"]>=0 {
            exec sddsplot -split=page -topline=@Description -group=page -sep=page -grap=sym,vary=sub,connect=sub,scale=2 \
              -xlabel=@ReadbackName -ylabel=@ActuatorName \
              -col=ReadbackValue,ActuatorValue $FFDir/$file "-title=$LLRFtype $file->$linkFile" &
    } else {
        exec sddsplot -split=page  -group=page -sep=page -grap=sym,vary=sub,connect=sub,scale=2 \
          -xlabel=@ReadbackName -ylabel=@ActuatorName \
          -col=ReadbackValue,ActuatorValue $FFDir/$file "-title=$LLRFtype $file->$linkFile" &
    }
    cd $oldDir
}

proc TransferRFPhase {args} {
    set install 0
    APSParseArguments {install}
    global tubeAmplifier rf12Amplifier FFDir LLRFtype
    if {[regexp {\#1} $tubeAmplifier]} {
	set tube1 1
    } elseif [regexp {\#2} $tubeAmplifier] {
	set tube1 2
    } else {
	SetMainStatus "Invalid tube amplifier: $tubeAmplifier"
	return
    }
    if {[regexp {\#1} $rf12Amplifier]} {
	set tube2 1
    } elseif [regexp {\#2} $rf12Amplifier] {
	set tube2 2
    } else {
	SetMainStatus "Invalid RF12 harmonic amplifier: $rf12Amplifier"
	return
    }
    set testfile  feedforwardTestFund${tube1}Harm${tube2}
    set oldDir [pwd]
    cd $FFDir/$LLRFtype
    set oldFile [file readlink $testfile]
    set newFile [APSNextGenerationedName -name $oldFile -newFile 1 -separator .]
    set tmpRoot /tmp/[APSTmpString]
    if [catch {exec sddsprocess $testfile $tmpRoot.1 -nowarnings \
		  "-match=col,ControlName=PAR:RF*:phaseShifter1Ch3,!" } result] {
	return -code error $result
    }
    if [catch {exec cavget -list=PAR:RF12:phaseShifter1Ch3,PAR:RF1:phaseShifter1Ch3 -pend=30} valList] {
	return -code error $valList
    }
    set val1 [lindex $valList 0]
    set val2 [lindex $valList 1]
    if [catch {exec sddsmakedataset -col=ControlName,type=string -data=PAR:RF12:phaseShifter1Ch3,PAR:RF1:phaseShifter1Ch3 \
		   -col=ReadbackName,type=string -data=PAR:RF12:phaseShifter1Ch3,PAR:RF1:phaseShifter1Ch3 \
		   -col=MaximumValue,type=double -data=[expr $val1 +2],[expr $val2+2] \
		   -col=MinimumValue,type=double -data=[expr $val1 -2],[expr $val2-2] $tmpRoot.2 } result] {
	return -code error "Error in creating test file: $result"
    }
    SetMainStatus "Transfer current RF phase to testfile -- $testfile.."
    if [catch {exec sddscombine $tmpRoot.1 $tmpRoot.2 $newFile -merge} result] {
	return -code error "Error in combining file: $result"
    }
    if $install {
       SetMainStatus "install ..."
	exec rm $testfile
	exec ln -s $newFile $testfile
    }
    cd $oldDir
    SetMainStatus "done."
}

proc RunFeedforward {args} {
    global inputFile runControlPV runControlDesc testFile LLRFtype
    global runControlPingTimeout Interval tubeAmplifier FFDir rf12Amplifier
    
    if ![string length $runControlPV] {
        SetMainStatus "run control pv is not provided.!"
        return
    }
    
    set runControlDesc "par harmonic tuner feedforward" 
    set switch 1
    while {1} {
        if [catch {exec cavget -list=PAR:Fnd:SW:DisableMessBO,PAR:Har:SW:DisableMessBO -num \
                       -pend=10 -printErrors} valList] {
            return -code error "Error: $valList"
        }
        if [regexp {1} $valList] {
            if $switch {
                SetMainStatus "Switching tubes, please wait ..."
                set switch 0
            }
            APSWaitWithUpdate -waitSeconds 1
        } else {
            break
        }
    }
   
    if {[regexp {\#1} $tubeAmplifier]} {
	set tube1 1
    } elseif [regexp {\#2} $tubeAmplifier] {
	set tube1 2
    } else {
        SetMainStatus "Invalid tube amplifier: $tubeAmplifier"
        return
    }
    if {[regexp {\#1} $rf12Amplifier]} {
	set tube2 1
    } elseif [regexp {\#2} $rf12Amplifier] {
	set tube2 2
    } else {
        SetMainStatus "Invalid RF12 harmonic amplifier: $rf12Amplifier"
        return
    }
    set inputFile parRFFeedForwardFund${tube1}Harm${tube2}.sdds
    set testFile $LLRFtype/feedforwardTestFund${tube1}Harm${tube2}.sdds
    
    if ![file exist $FFDir/$inputFile] {
        SetMainStatus "$FFDir/$inputFile does not exist"
        return
    }
    if ![file exist $FFDir/$testFile] {
        SetMainStatus "$FFDir/$testFile does not exist"
        return
    }
    
    SetMainStatus "Running par feedforward for  fund$tubeAmplifier and Harm $rf12Amplifier ..."
   # SetMainStatus "feedforward filename is $FFDir/$inputFile."
    AbortFeedforward
    APSExecLog .parfeedforward -width 80 \
        -unixCommand \
        "sddsfeedforward $FFDir/$inputFile -interval=$Interval -verbose -infiniteLoop -runControlPV=string=$runControlPV,pingTimeout=$runControlPingTimeout \"-runControlDescription=$runControlDesc\" -testValue=$FFDir/$testFile"
}

proc AbortFeedforward {args} {
    set full 0
    APSParseArguments {full}
    global runControlPV
    if [catch {exec cavput -list=$runControlPV.ABRT=1 -pend=30} result] {
	SetMainStatus "Error in aborting feedforward: $result"
	return
    }
    catch {exec cawait -waitfor=$runControlPV.RUN,equal=0}
}

proc FeedforwardInfo {args} {
    global runControlPV
    exec medm -x -attach -macro RCPV=$runControlPV ./sr/psApp/APSRunControlSingle.adl &
}

proc APSControlLawTestValuesButton {args} {
    global testFile FFDir tubeAmplifier  rf12Amplifier LLRFtype

   if {[regexp {\#1} $tubeAmplifier]} {
	set tube1 1
    } elseif [regexp {\#2} $tubeAmplifier] {
	set tube1 2
    } else {
	SetMainStatus "Invalid tube amplifier: $tubeAmplifier"
	return
    }
    if {[regexp {\#1} $rf12Amplifier]} {
	set tube2 1
    } elseif [regexp {\#2} $rf12Amplifier] {
	set tube2 2
    } else {
	SetMainStatus "Invalid RF12 harmonic amplifier: $rf12Amplifier"
	return
    }
    set testfile  $LLRFtype/feedforwardTestFund${tube1}Harm${tube2}.sdds
    
    if ![file exist $FFDir/$testfile] {
	SetMainStatus "test file does not exist."
	return
    }
    set command \
   "sddssnapshot $FFDir/$testfile -pipe=output | sddsprocess -pipe \"-def=col,InBounds,MinimumValue Value < pop pop ? Value MaximumValue < pop pop ? 1 : 0 $ : 0 $,type=long\" | sddsprintout -pipe=in -col=ControlName,format=%28s -col=(MinimumValue,Value,MaximumValue,InBounds)"

    APSExecLog .testInfo -unixCommand $command -width 88
}

proc Relink {args} {
    global LLRFtype FFDir
    set oldDir [pwd]
    cd $FFDir
    
    foreach type {Fund1Harm1 Fund1Harm2 Fund2Harm1 Fund2Harm2} dir {Harm1 Harm2 Harm1 Harm2} {
	catch {exec rm parRFFeedForward$type.sdds}
	exec ln -s $LLRFtype/$dir/parRFFeedForward$type.sdds parRFFeedForward$type.sdds
    }
    cd $oldDir
}
Relink
