# This file is obsolete

# KnLValues only uses SCR file and magnet excitation files
# there is no model adjustments such as in procedure setpoints.
proc APSMpMagnetKnLValues {args} {
    set SCRFile ""
    set xrefFileList ""
    set energy 7 
    set outputFileDir .
    set outputFileRoot ""
    set BRhoPVName ""
    set statusCallback ""
    set abortVariable ""

    if [APSStrictParseArguments {SCRFile xrefFileList \
                                   energy outputFileDir outputFileRoot \
                                   BRhoPVName \
                                   statusCallback abortVariable}] {
        return -code error "APSMpMagnetKnLValues: Invalid arguments."
    }
    if ![string length $SCRFile]  {
        return -code error "APSMpMagnetKnLValues: No SCR file selected."
    }
    if {![string length $xrefFileList] || \
          ![string length $outputFileDir] || \
          ![string length $outputFileRoot] || \
          $energy<0} {
        return -code error "APSMpMagnetKnLValues: Invalid file parameters."
    }
    if [string length $abortVariable] {
        global $abortVariable
        set $abortVariable 0
    }

    set rigidity [expr $energy * 1000.0 / 299.792458 ]
    #set valuesFile /tmp/[APSTmpString].values
    #set interpResults /tmp/[APSTmpString].results

    if ![file exists $SCRFile] {
        return -code error "APSMpMagnetKnLValues: Can't find file $SCRFile."
    }
    if {[catch {exec sdds2stream $SCRFile -parameter=SnapshotDescription -page=1 -noquotes} results]} {
        return -code error "APSMpMagnetKnLValues:: Invalid SCR file"
    }    
    if {[string first "Limited save:" $results] != -1} {
        return -code error "APSMpMagnetKnLValues:: LIMITED SAVE SCR files cannot be used for this procedure."
    }
    
    if [string length $statusCallback] {
        eval $statusCallback {"Calculating KnL values..."}
    }
    # expect Length data in xref file
    #set parameterData /tmp/[APSTmpString]
    set KnLfileList ""
    foreach xFile $xrefFileList {
        set tmpRoot /tmp/[APSTmpString]
        if [catch {exec sddsxref $xFile $SCRFile -pipe=out -nowarning \
                     -match=SetPVName=ControlName -take=ValueString \
                     | sddsprocess -pipe \
                     -print=parameter,BRhoPVName,$BRhoPVName \
                     "-define=parameter,BRho,$rigidity,units=T m,description=Beam rigidity" \
                     "-print=parameter,XrefFilename,$xFile,description=Cross-reference file used to make this file" \
                     "-print=parameter,SCRFilename,$SCRFile,description=SCR parameter file used to make this file" \
                     -scan=col,I,ValueString,%lf \
                     | sddsinterpset -pipe \
                     -data=fileCol=ExcitationFile,interpolate=BnL,functionOf=I,column=I \
                     -aboveRange=extrapolate -belowRange=extrapolate \
                     | sddsprocess -pipe -nowarning \
                     "-define=col,KnL,BnL BRho / FamilyCalFactor * FamilyCalSign *,units=SI" \
                     "-define=col,Kn,KnL Length /" \
                     -define=col,ParameterValue,Kn \
                     | sddsconvert -pipe=in ${tmpRoot}.KnL \
                     -retain=col,MagnetName,ElementName,Length,I,BnL,KnL,Kn,ElementParameter,ParameterValue,ElementType \
                 } result ] {
            return -code error "APSMpMagnetKnLValues: processing $xFile: $result"
        }
        lappend KnLfileList ${tmpRoot}.KnL
    }
    if [catch {eval exec sddscombine $KnLfileList $outputFileDir/$outputFileRoot.KnL \
                 -merge -overWrite \
             } result ] {
        return -code error "APSMpMagnetKnLValues: $result"
    }
    catch {eval file delete $KnLfileList}
    if [string length $statusCallback] {
        eval $statusCallback "Done."
    }
    return
}

proc APSMpMagnetSetpoints {args} {
    set paramFile ""
    set xrefFileList ""
    set templateFileList ""
    set energy 7
    set outputFileDir .
    set outputFileRoot ""
    set BRhoPVName ""
    set statusCallback ""
    set abortVariable ""
    # paramFile needs to have the L parameter retained
    # so that the produce K1 L can be calculated.
    if [APSStrictParseArguments {paramFile xrefFileList templateFileList \
                                   energy outputFileDir outputFileRoot \
                                   BRhoPVName \
                                   statusCallback abortVariable}] {
        return -code error "APSMpMagnetSetpoints: Invalid arguments."
    }
    if ![string length $paramFile] {
        return -code error "APSMpMagnetSetpoints: No parameters file given."
    }
    if ![file exists $paramFile] {
        return -code error "APSMpMagnetSetpoints: Cannot find file $paramFile."
    }

    if {![string length $xrefFileList] || \
          ![string length $templateFileList] || \
          ![string length $outputFileDir] || \
          ![string length $outputFileRoot] || \
         $energy<0} {
        return -code error "APSMpMagnetSetpoints: Invalid parameters."
    }
    if {[llength $xrefFileList] != [llength $templateFileList]} {
        return -code error "APSMpMagnetSetpoints: Lists for xref files and template files are not of equal lengths"
    }

    if {$abortVariable != ""} {
        global $abortVariable
        set $abortVariable 0
    }
    set rigidity [expr $energy * 1000.0 / 299.792458 ]
    set snpList ""
    set stdList ""
    set SDDSList ""
    foreach xFile $xrefFileList tFile $templateFileList {
        if [string length $statusCallback] {
            eval $statusCallback {"Processing $paramFile data with file $xFile..."}
        }
        set tmpRoot /tmp/[APSTmpString]
        set snap ${tmpRoot}.snp
        set stand ${tmpRoot}.std
        set valuesFile ${tmpRoot}.values
        set interpResults ${tmpRoot}.results
	set KnValues ${tmpRoot}.Kn
	set LValues ${tmpRoot}.L
	set KnLValues ${tmpRoot}.KnL
	# create file KnLValues that has columns: ElementName KnL
	#--- Latest elegant param file can have K1 for sext

        # somehow file $paramFile only has sextupoles.
        # don't lose the column ElementType it is need on a potential call to APSMpAdjustMagnetSetpoints
	if [catch {exec sddsprocess $paramFile -pipe=out \
		       -print=col,TagName,%s%s,ElementType,ElementParameter \
		       "-match=col,TagName=*QUAD*K1,TagName=*SEXT*K2,|" \
		       | sddsconvert -pipe=in $KnValues \
		       -retain=col,ElementName,ParameterValue,ElementType,TagName\
		       -rename=col,ParameterValue=Kn} result ] {
            return -code error "APSMpMagnetSetpoints(1): $result"
        }
	if [catch {exec sddsprocess $paramFile -pipe=out -noWarning \
		       -match=col,ElementParameter=L \
		       | sddsconvert -pipe=in $LValues \
		       -retain=col,ElementName,ParameterValue \
		       -rename=col,ParameterValue=L \
		   } result ] {
            return -code error "APSMpMagnetSetpoints(2): $result"
        }
	if [catch {exec sddsxref $KnValues $LValues -pipe=out -noWarning \
		       -take=L -match=ElementName \
		       | sddsprocess -pipe=in $KnLValues \
		       "-def=col,KnL,Kn L *"
	} result ] {
            return -code error "APSMpMagnetSetpoints(3): $result"
        }
	
# File $xFile has columns ElementName ExcitationFile.
# Add to this the column KnL from file KnLValues.
# Column BnL is then calculated from KnL.
        if [string length $statusCallback] {
            eval $statusCallback {"Processing $xFile with $KnLValues..."}
        }
        # removed matching of HeadOfFamily
        if [catch {exec sddsxref $xFile $KnLValues -pipe=out \
                       -match=ElementName -take=KnL \
                       | sddsprocess -pipe \
                       "-rpn_ex=$rigidity sto H" \
                       -print=parameter,BRhoPVName,$BRhoPVName \
                       "-define=parameter,BRho,$rigidity,units=T m,description=Beam rigidity" \
                       "-print=parameter,XrefFilename,$xFile,description=Cross-reference file used to make this file" \
                       "-print=parameter,ParamFile,$paramFile,description=Lattice parameter file used to make this file" \
                       "-define=col,BnL,KnL H * FamilyCalFactor / FamilyCalSign *,units=SI" \
                       | sddsinterpset -pipe=in $interpResults \
                       -data=fileCol=ExcitationFile,interpolate=I,functionOf=BnL,column=BnL \
                       -aboveRange=extrapolate -belowRange=extrapolate \
                   } result ] {
            return -code error "APSMpMagnetSetpoints(4): $result"
        }
        
        # make *.snp file (compatible with SCR file)
        if [catch {exec sddsconvert $interpResults -pipe=out \
                     -retain=col,SetPVName,I \
                     -rename=column,SetPVName=ControlName \
                     | sddsprocess -pipe=in $snap  \
                     -print=column,ControlType,pv \
                     -define=column,Count,1,type=long \
                     -print=column,Lineage,- \
                     -print=column,ValueString,%f,I \
                     -print=para,SnapType,Absolute \
                 } result ] {
            return -code error "APSMpMagnetSetpoints(5): $result"
        }

        # make standardize file $output.std from template file
        if [catch {exec sddsxref $tFile $interpResults -pipe=out \
                     -nowarning \
                     -match=ControlName=DeviceName -take=I,ElementName,MaximumCurrent \
                     | sddsconvert -pipe=input $stand \
                     -rename=column,I=Finish,MaximumCurrent=To \
                 } result ] {
            return -code error "APSMpMagnetSetpoints(6): $result"
        }
        lappend snpList $snap
        lappend resultsList $interpResults
        lappend stdList $stand
    }
    if [catch {eval exec sddscombine $snpList $outputFileDir/$outputFileRoot.snp \
                 -merge -overWrite
        eval exec sddscombine $resultsList $outputFileDir/$outputFileRoot.results \
                 -merge -overWrite
        eval exec sddscombine $stdList $outputFileDir/$outputFileRoot.std \
                 -merge -overWrite
             } result ] {
        return -code error "APSMpMagnetSetpoints(7): $result"
    }
    if {$statusCallback != ""} {
        eval $statusCallback "Done."
    }
    return
}

proc APSMpAdjustMagnetSetpoints {args} {
    set newSnapFile ""
    set referenceSnapFile ""
    set referenceSCRFile ""
    set adjustmentModel none
    set outputFileDir .
    set outputFileRoot ""
    set statusCallback ""
    set abortVariable ""

    if [APSStrictParseArguments {newSnapFile referenceSnapFile \
                                   referenceSCRFile adjustmentModel \
                                   outputFileDir outputFileRoot \
                                   statusCallback abortVariable}] {
        return -code error "APSMpAdjustMagnetSetpoints: Invalid arguments."
    }

    if {$newSnapFile=="" || $referenceSnapFile=="" || \
          $referenceSCRFile=="" || $adjustmentModel=="" || \
          $outputFileDir=="" || $outputFileRoot=="" } {
        return -code error "APSMpAdjustMagnetSetpoints: Invalid arguments."
    }
    if ![string compare $adjustmentModel none] {
        return
    }
    if [string length $statusCallback] {
        eval $statusCallback {"Processing $newSnapFile data with files $referenceSnapFile and $referenceSCRFile..."}
    }
    if ![file exists $newSnapFile] {
        return -code error "APSMpAdjustMagnetSetpoints: Cannot find file $newSnapFile."
    }
    if ![file exists $referenceSnapFile] {
        return -code error "APSMpAdjustMagnetSetpoints: Cannot find  file $referenceSnapFile."
    }
    if ![file exists $referenceSCRFile] {
        return -code error "APSMpAdjustMagnetSetpoints: Cannot find  file $referenceSCRFile."
    }
    set tmproot /tmp/[APSTmpString]
    if {$adjustmentModel == "none"} {
        return
    }
    # Keep only magnet settings from SCR file, i.e. those control names
    # that are also contained in the reference snapshot file.
    if [catch {exec sddsselect $referenceSCRFile $referenceSnapFile -pipe=out \
                 -match=ControlName \
                 | sddsprocess -pipe=in ${tmproot}.SCR \
                 -scan=col,SCRSetpoint,ValueString,%lf \
             } result ] {
        return -code error "APSMpAdjustMagnetSetpoints(0): $result"
    }
    if [catch {exec sddsprocess $referenceSnapFile ${tmproot}.ref \
                 -scan=col,RefSetpoint,ValueString,%lf \
             } result ] {
        return -code error "APSMpAdjustMagnetSetpoints(1): $result"
    }
    switch $adjustmentModel {
        differenceInI {
            set operator1 -
            set operator2 +
        }
        ratioInI {
            set operator1 /
            set operator2 *
        }
    }
    # only adjust quadrupoles
    if [catch {exec sddsprocess $newSnapFile -pipe=out \
                 -scan=col,NewSetpoint,ValueString,%lf \
                 | sddsxref -pipe ${tmproot}.SCR \
                 -match=ControlName -take=SCRSetpoint \
                 | sddsxref -pipe ${tmproot}.ref \
                 -match=ControlName -take=RefSetpoint \
                 | sddsprocess -pipe \
                 "-def=col,IChange,NewSetpoint RefSetpoint $operator1,units=A" \
                 "-def=col,AdjustedSetPoint,SCRSetpoint IChange $operator2,units=A,description=I setpoint after doing $adjustmentModel adjustment model" \
                 | tee $outputFileDir/${outputFileRoot}.all.snp \
                 | sddsprocess -pipe=in $outputFileDir/${outputFileRoot}.Q.snp  \
                 -reprint=col,ValueString,%lf,AdjustedSetPoint \
             } result ] {
        return -code error "APSMpAdjustMagnetSetpoints(2): $result"
    }
    if [catch {exec sddsprocess $outputFileDir/${outputFileRoot}.all.snp \
                 $outputFileDir/${outputFileRoot}.S.snp \
                 -match=col,ControlName=*:S* -noWarning \
             } result ] {
        return -code error "APSMpAdjustMagnetSetpoints(2): $result"
    }
    if [catch {exec sddscombine $outputFileDir/${outputFileRoot}.Q.snp \
                 $outputFileDir/${outputFileRoot}.S.snp \
                 $outputFileDir/${outputFileRoot}.snp \
                 -merge -overWrite \
             } result ] {
        return -code error "APSMpAdjustMagnetSetpoints(2): $result"
    }
    file delete -force $outputFileDir/${outputFileRoot}.Q.snp \
      $outputFileDir/${outputFileRoot}.S.snp

    if [string length $statusCallback] {
        eval $statusCallback "Done."
    }
    return
}

proc APSMpAdjustParameterFile {args} {
    set referenceSCRFile ""
    set xrefFileList ""
    set energy 7
    set refParamFile ""
    set paramFile ""
    set BRhoPVName ""
    set outputParamFile ""
    set statusCallback ""
    if [APSStrictParseArguments {referenceSCRFile xrefFileList energy \
                                   refParamFile paramFile BRhoPVName \
                                   outputParamFile statusCallback}] {
        return -code error "APSMpAdjustParameterFile: Invalid arguments."
    }
    if {$referenceSCRFile=="" || $xrefFileList=="" || $refParamFile=="" || \
          $paramFile=="" || $outputParamFile=="" } {
        return -code error "APSMpAdjustParameterFile(1): Invalid arguments."
    }
    # convert I_ref to K1_ref, but only for quadrupoles.
    set tmproot [APSTmpString]
    set foundQxrefFile 0
    foreach xref $xrefFileList {
        #determine type of file from name
        if [regexp Q [file tail $xref]] {
            set foundQxrefFile 1
            if [catch {APSMpMagnetKnLValues -SCRFile $referenceSCRFile \
                         -xrefFileList $xref \
                         -energy $energy  -BRhoPVName $BRhoPVName \
                         -outputFileDir /tmp \
                         -outputFileRoot ${tmproot} \
                         -statusCallback $statusCallback \
                     } result ] {
                return -code error "APSMpAdjustParameterFile(2): $result"
            }
        }
    }
    # if there was no xref file with quadrupoles, then there
    # is no adjustments for this procedure to do.
    if !$foundQxrefFile {
        file copy -force $paramFile $outputParamFile
        if [string length $statusCallback] {
            eval $statusCallback {"Done. No change in parameter file needed."}
        }
        return  
    }
    # determine sum of K1(I_ref) + (K1 - K1_ref) for quads
    # file             column name
    # $tmpfile.KnL     Kn, which is K1(I_ref) above
    # $refParamFile    K1Reference
    # $paramFile       K1
    # Filter the parameter files for the quadrupole K1 ParameterName
    if [string length $statusCallback] {
        eval $statusCallback {"Calculating new K1's..."}
    }
    # note that the skew quads are inadvertedly included here, as
    # there is no easy way to filter them out.
    if [catch {exec sddsprocess $refParamFile /tmp/$tmproot.refK1 \
                 -match=col,ElementParameter=K1,ElementType=*QUAD*,& \
             } result ] {
        return -code error "APSMpAdjustParameterFile(3): $result"
    }
    if [catch {exec sddsprocess $paramFile /tmp/$tmproot.K1 \
                 -match=col,ElementParameter=K1,ElementType=*QUAD*,& \
             } result ] {
        return -code error "APSMpAdjustParameterFile(4): $result"
    }
    if [catch {exec sddsprocess $paramFile /tmp/$tmproot.other \
                 -match=col,ElementParameter=K1,ElementType=*QUAD*,&,! \
             } result ] {
        return -code error "APSMpAdjustParameterFile(5): $result"
    }
    # Something to keep in mind: Since the KnL file /tmp/$tmproot.KnL 
    # doesn't include skew quads the final parameter file 
    # will not have skew quad K1's.
    if [catch {exec sddsxref /tmp/$tmproot.KnL /tmp/$tmproot.refK1  -pipe=out \
                   -match=ElementName -take=ParameterValue \
                 -rename=col,ParameterValue=K1Reference \
                 | sddsxref -pipe /tmp/$tmproot.K1 \
                 -match=ElementName -take=ParameterValue \
                 -rename=col,ParameterValue=K1 \
                 | sddsprocess -pipe=in /tmp/$tmproot.newK1 \
                 "-redef=col,ParameterValue,Kn K1 + K1Reference -" \
             } result ] {
        return -code error "APSMpAdjustParameterFile(6): $result"
    }
    if [catch {exec sddscombine /tmp/$tmproot.newK1 /tmp/$tmproot.other \
                 $outputParamFile -overWrite -merge \
             } result ] {
        return -code error "APSMpAdjustParameterFile(7): $result"
    }
    if [string length $statusCallback] {
        eval $statusCallback "Done."
    }
}
