#!/bin/sh  
# \
exec oagtclsh "$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)]

APSStandardSetup

proc ConvertWake {args} {
    APSStrictParseArguments {type output}

    if {$type == "WXq"} {
        if {[file exists scratch.WXq_AT_XY.0001]} {
            set inputfile scratch.WXq_AT_XY.0001
        } else {
            set inputfile scratchdir/scratch.WXq_AT_XY.0001
        }
        set outputfile $output.uwake
        if {[catch {exec awk {/<x>,<y>/ { print $9 $10 }} $inputfile | \
                    sed -e {s/,/\n/g} -e {s/)//g}} results]} {
            puts "gdf2wake: Error $results"
            exit
        }
    } elseif {$type == "WYq"} {
        if {[file exists scratch.WYq_AT_XY.0001]} {
            set inputfile scratch.WYq_AT_XY.0001
        } else {
            set inputfile scratchdir/scratch.WYq_AT_XY.0001
        }
        set outputfile $output.vwake
        if {[catch {exec awk {/<x>,<y>/ { print  $8 $9 }} $inputfile | \
                    sed -e {s/,/\n/g} -e {s/)\[m\]\"//g}} results]} {
            puts "gdf2wake: Error $results"
            exit
        }
    } elseif {$type == "Wq"} {
        if {[file exists scratch.Wq_AT_XY.0001]} {
            set inputfile scratch.Wq_AT_XY.0001
        } else {
            set inputfile scratchdir/scratch.Wq_AT_XY.0001
        }
        set outputfile $output.wwake
        if {[catch {exec awk {/\(x,y\)\=/ { print  $6 $7 }} $inputfile | \
                    sed -e {s/,/\n/g} -e {s/)//g}} results]} {
            puts "gdf2wake: Error $results"
            exit
        }
    }
    set BeamX [lindex $results 0]
    set BeamY [lindex $results 1]

    if {[catch {exec awk {/total charge\=/ {print $5}} $inputfile} results]} {
        puts "gdf2wake: Error $results"
        exit
    }
    set Charge $results

    if {[catch {exec awk {/\[xyz\]loss/ {print $9 $10 $11}}  $inputfile | \
                sed -e {s/,/\n/g}  -e {s/,/\n/g}  -e {s/)//g}} results]} {
        puts "gdf2wake: Error $results"
        exit
    }
    set kx [lindex $results 0]
    set ky [lindex $results 1]
    set kz [lindex $results 2]

    if {[catch {exec awk { { if ($2=="BEGIN_CHARGE") 
                                 exit
                             else if (($1=="$") || ($1=="#") || ($1=="%") || ($1=="@point") || NF==0)\
                                 next
                             else
                                 {print }}} $inputfile} results]} {
        puts "gdf2wake: Error $results"
        exit
    }
    set data $results

    set fid [open $outputfile w]
    puts $fid {SDDS1
&parameter name=BeamX symbol=BeamX description="Beam Offset in X" units=m type=double &end
&parameter name=BeamY symbol=BeamY description="Beam Offset in Y" units=m type=double &end
&parameter name=Charge type=double units=C &end
&parameter name=kx symbol=kx description="Loss in X" units="VAs" type=double &end
&parameter name=ky symbol=ky description="Loss in Y" units="VAs" type=double &end
&parameter name=kz symbol=kz description="Loss in Z" units="VAs" type=double &end
&column name=s     symbol=s     description="Distance"        units=m     type=double &end}
    if {$type == "WXq"} {
        puts $fid {&column name=Uwake symbol=Uwake description="Horizontal Wake" units="V/C" type=double &end}
    } elseif {$type == "WYq"} {
        puts $fid {&column name=Vwake symbol=Vwake description="Vertical Wake" units="V/C" type=double &end}
    } elseif {$type == "Wq"} {
        puts $fid {&column name=Wwake symbol=Wwake description="Longitudinal Wake" units="V/C" type=double &end}
    }
    puts $fid {&data mode=ascii no_row_counts=1 &end}
    puts $fid $BeamX
    puts $fid $BeamY
    puts $fid $Charge
    puts $fid $kx
    puts $fid $ky
    puts $fid $kz
    puts $fid $results
    close $fid
}

proc ConvertDensity {args} {
    APSStrictParseArguments {output}
    if {[file exists scratch.Wq_AT_XY.0001]} {
        set inputfile scratch.Wq_AT_XY.0001
    } else {
        set inputfile scratchdir/scratch.Wq_AT_XY.0001
    }
    set outputfile $output.density

    if {[catch {exec awk {/\(x,y\)\=/ { print  $6 $7 }} $inputfile | sed -e {s/,/\n/g} -e {s/)//g}} results]} {
        puts "gdf2wake: Error $results"
        exit
    }
    set BeamX [lindex $results 0]
    set BeamY [lindex $results 1]

    if {[catch {exec awk {/total charge\=/ {print $5}} $inputfile} results]} {
        puts "gdf2wake: Error $results"
        exit
    }
    set Charge $results

    if {[catch {exec awk {/\[xyz\]loss/ {print $9 $10 $11}}  $inputfile | \
                sed -e {s/,/\n/g}  -e {s/,/\n/g}  -e {s/)//g}} results]} {
        puts "gdf2wake: Error $results"
        exit
    }
    set kx [lindex $results 0]
    set ky [lindex $results 1]
    set kz [lindex $results 2]


    if {[catch {exec awk { BEGIN{start==0}
                         { if ($2=="linecolor=") 
                             start = 1    
                           if ($2=="END_CHARGE")
                             start = 0
                           if ((start == 1) && ($1 != "%")) 
                             {print}} } $inputfile} results]} {
        puts "gdf2wake: Error $results"
        exit
    }
    set data $results

    set fid [open $outputfile w]
    puts $fid {SDDS1
&parameter name=BeamX symbol=BeamX description="Beam Offset in X" units=m type=double &end
&parameter name=BeamY symbol=BeamY description="Beam Offset in Y" units=m type=double &end
&parameter name=Charge type=double units=C &end
&parameter name=kx symbol=kx description="Loss in X" units="VAs" type=double &end
&parameter name=ky symbol=ky description="Loss in Y" units="VAs" type=double &end
&parameter name=kz symbol=kz description="Loss in Z" units="VAs" type=double &end
&column name=s     symbol=s     description="Distance"        units=m     type=double &end
&column name=Density symbol=Density description="Charge Density" units="C/m" type=double &end
&data mode=ascii no_row_counts=1 &end}
    puts $fid $BeamX
    puts $fid $BeamY
    puts $fid $Charge
    puts $fid $kx
    puts $fid $ky
    puts $fid $kz
    puts $fid $results
    close $fid
}

proc ProcessDensity {args} {
    APSStrictParseArguments {output}

    if {[catch {exec sddsinterp $output.density $output.tmp -col=s,Density \
		    -fileValues=$output.wwake,column=s -aboveRange=value=0} results]} {
	puts "gdf2wake: Error $results"
	exit
    }
    
    file rename -force $output.tmp $output.density
    
    if {[catch {exec sddsxref $output.uwake $output.vwake $output.wwake $output.density \
		    -equate=s -nowarnings $output.wake} results]} {
	puts "gdf2wake: Error $results"
	exit
    }
    
    if {[catch {exec sddsprocess $output.wake -nowarn "-redefine=col,Uwake,Uwake -1.0 *,units=V/C,symbol=Uwake" \
		    "-redefine=col,Vwake,Vwake -1.0 *,units=V/C,symbol=Vwake"} results]} {
	puts "gdf2wake: Error $results"
	exit
    }

    file delete $output.wake~ $output.uwake $output.vwake $output.wwake $output.density
}

proc SimulationFinished {args} {
    if {[catch {exec grep -i "This is the normal end"  WHAT-GDFIDL-DID-SPIT-OUT} results]} {
	return 0
    }
    return 1
}

proc CalculateWake {args} {
    set fid [open wakes.pp w]
    puts $fid {-general, infile=@last
-wakes
   onlyplotfiles= yes
   doit}
   close $fid

    if {[catch {exec gd1.pp < wakes.pp} results]} {
	puts "gdf2wake: CalculateWake: $results"
    }
    file delete wakes.pp
}

set args $argv
set output ""
set calcWake yes
APSStrictParseArguments {output calcWake}
if {[llength $output] != 1} {
    puts "Usage: gdf2wake -output <rootname> -calcWake <no>"
    exit
}


if {![SimulationFinished]} {
    puts "The simulation in [pwd] is not finished."
    puts "Please check the output file."
    exit
}
if {$calcWake == "yes"} {
    CalculateWake
}
ConvertWake -type WXq -output $output
ConvertWake -type WYq -output $output
ConvertWake -type Wq  -output $output
ConvertDensity -output $output
ProcessDensity -output $output

