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



set auto_path [linsert $auto_path 0 /usr/local/oag/apps/lib/$env(HOST_ARCH)]
set auto_path [linsert $auto_path 0 /usr/local/oag/lib_patch/$env(HOST_ARCH)]
APSDebugPath

wm geometry . +10+10

set args $argv

APSApplication . -name BoosterSteeringConfig -version 1 \
  -overview {This application allows steering configuration of booster.  You may choose the lattice, which monitors and correctors to use, and restrict your choices to only good components.}
set hBooSteeringConfigStatus ""
APSScrolledStatus .hstatus -parent .userFrame -width 60 \
  -textVariable hBooSteeringConfigStatus 

set sectorList ""
for {set b 1} {$b<5} {incr b} {
    for {set c 0} {$c<10} {incr c} {
	lappend sectorList B${b}C$c
	lappend commandList SelectBPMandCorrectors
    }
}

proc SetStatus {text} {
    global hBooSteeringConfigStatus
    set hBooSteeringConfigStatus $text
    update
}

proc SelectBPMandCorrectors {args} {
    global Sector sectorList SteeringBPM
   # UnselectAll
    set refDir /home/helios/oagData/booster/localSteering
    set tmpRoot /tmp/[APSTmpString]
    set colList {Corr0 Corr1 Corr2 Corr3}
    set configFile /home/helios/oagData/booster/localSteering/steeringConfig.sdds
    foreach plane {h v} Plane {H V} {
	set rootname ${plane}BooSteering
	set name ${Sector}$Plane
	if {$name=="B2C9V"} {
	    continue
	}
	if [catch {exec sddsprocess $configFile $tmpRoot.$plane -match=par,Sector=${Sector}$Plane } result] {
	    return -code error "$Sector not found in $refFile."
	}
	set mon1 [exec sdds2stream -par=BPM1 $tmpRoot.$plane]
	set mon2 [exec sdds2stream -par=BPM2 $tmpRoot.$plane]
	set SteeringBPM(${Sector}.${plane}BPM1) $mon1
	set SteeringBPM(${Sector}.${plane}BPM2) $mon2
	set itemList [list P1 P2 [string toupper $plane]]
	APSSetSRSectorButtons -mode all-off -rootname ${rootname} -sectorList $sectorList \
              -sectorCount 40 -itemList $itemList
	puts $colList
	foreach col $colList {
	    set $col [exec sdds2stream -par=$col $tmpRoot.$plane]
	    set name [set $col]
	    global ${rootname}$name ${rootname}CBWidget
	    [set ${rootname}CBWidget($name)] invoke
	    #include non-bound BPMs
	}
	set bpmList [exec sdds2stream -col=BPMName $tmpRoot.$plane]
        puts $bpmList
	foreach bpm $bpmList {
	    global ${rootname}$bpm ${rootname}CBWidget
	    [set ${rootname}CBWidget($bpm)] invoke
	}
    }
}

proc MakeSelectionFrame {args} {
    global sectorList 
    set tabList {"Horizontal" "Vertical"}
    #set widgetList [APSTabFrame .tabs -parent .userFrame -width 1200 -height 250 \
     #             -labelList [join $tabList] -label "" -tabPosition n]
    APSFrame .h -parent .userFrame
    set w1 .userFrame.h.frame
     APSFrame .v -parent .userFrame
    set w2 .userFrame.v.frame
    
    set sectorList ""
    for {set b 1} {$b<5} {incr b} {
	for {set c 0} {$c<10} {incr c} {
	    lappend sectorList B${b}C$c
	}
    }
    global vBooSteeringConfigStatus
    set vBooSteeringConfigStatus ""
    foreach plane {h v} widget [list $w1 $w2] {
	set itemList [list P1 P2 [string toupper $plane]]
	set rootname ${plane}BooSteering
	if {$plane=="v"} {
	    APSScrolledStatus .vstatus -parent .userFrame -width 60 \
		-textVariable vBooSteeringConfigStatus 
	}
	APSSRSectorButtons .bpmcorr -parent $widget -rootname $rootname  \
	    -label "$plane plane BPM/correctors" -sectorList $sectorList  \
	    -itemList $itemList -separateCountButton 1 \
	    -itemLabelList $itemList \
	    -description "boostesr $plane" \
	    -orientation horizontal -sectorControl 1 -packOption "-side top"  -missingList {B2C9V} 
    }
    global Sector commandList
    set Sector B1C0
    APSRadioButtonFrame .sel -parent .userFrame -label "Select Sector" \
	-variable Sector -buttonList $sectorList -valueList $sectorList -limitPerRow 4 -commandList $commandList
}

proc MakeSectorMatrix {args} {
    set sector ""
    APSParseArguments {sector}

    global mainDir matrixDir twissFile
    set tmpRoot /tmp/[APSTmpString]
    
    set steeringDir $mainDir/$sector
    foreach plane {h v} {
        set Plane [string toupper $plane]
        if [catch {exec sddsconvert $steeringDir/irm.$plane -pipe=out -retain=col,ControlName \
                     | sddsxref -pipe $twissFile -match=ControlName=ElementName -take=s -nowarnings \
                     | sddsprocess -pipe=in $tmpRoot.$plane.1 -process=s,first,s0 -process=s,last,s1 } result] {
            return -code error "MakeSectorMatrix1: $result"
        }
        APSAddToTempFileList -ID 1 -fileList $tmpRoot.$plane.1
        set s0 [exec sdds2stream -par=s0 $tmpRoot.$plane.1]
        set s1 [exec sdds2stream -par=s1 $tmpRoot.$plane.1]
        set corrList [exec sdds2stream -col=ControlName $tmpRoot.$plane.1]
        if [catch {exec sddsprocess $twissFile $tmpRoot.$sector.bpms -filter=col,s,$s0,$s1 -match=col,ElementType=MONI  } result] {
            return -code error "MakeSectorMatrix2: error getting in bound bpms for $sector: $result"
        }
        set bpmList [exec sdds2stream -col=ElementName $tmpRoot.$sector.$bpm]
        set opt ""
        foreach bpm $bpmList {
            if ![string length $opt] {
                set opt -match=col,BPMName=$bpm
            } else {
                append opt ,BPMName=$bpm,|
            }
        }
        if [catch {eval exec sddsprocess $matrixDir/${plane}.default -pipe=out $opt \
                     | sddsconvert -pipe -del=col,s \
                     | sddsxref -pipe $tmpRoot.$sector.bpm -match=BPMName=ElementName -take=s nowarnings \
                     | sddssort -pipe -col=s \
                     | sddsconvert -pipe=in -retain=col,BPMName,[join $corrLisst ,] \
                     $steeringDir/$plane.steering.rm } result] {
            return -code error "Making sector matrix3b: $result"
        }   
    }
}

proc Generate {args} {
    global mainDir Sector sectorList rampTimeRange singularValues SteeringBPM matrixDir
    
    if {$Sector=="B2C9"} {
	 APSAlertBox [APSUniqueName .] -errorMessage \
	    "Skip B2C9 sector since B2C9V does not exit!"
        return 1
    }
    set dataDir $mainDir/$Sector
    if ![file exist $dataDir] {
	exec mkdir -p $dataDir
    }
    cd $mainDir
    set sectorCount [llength $sectorList]
    SetStatus "Generating irm..."
    foreach plane {h v} Plane {H V} coord {x y} {
	set rootname ${plane}BooSteering
	set corCount [APSCountSRConfig -rootname $rootname -itemList $Plane -sectorCount $sectorCount -sectorList $sectorList]
	set confirmQuery ""
	set confirm 0
	if {!$corCount} {
	    set confirm 1
	    append confirmQuery "\nNo $plane correctors chosen."
	}
	if [APSCountSRConfig -rootname $rootname -itemList {P1 P2} -sectorCount $sectorCount -sectorList $sectorList]==0 {
	    set confirm 1
	    append confirmQuery "\nNo monitors chosen."
	}
	if {$confirm &&
	    [APSMultipleChoice [APSUniqueName .] -question "Possible problem: $confirmQuery" \
		 -labelList {"Cancel (recommended)" Continue} -returnList {0 1}]==0} {
	    return
	}
	#write config
	if [catch {APSWriteSRConfig -rootname $rootname -filename $Sector/config.$plane -sectorList $sectorList \
		       -nameTypeList {Monitor Corrector} -interactive 1 -updateDatabase 0 \
		       -PVTypeList {plain plain} \
		       -suffixLists [list {P1 P2} $Plane] -rampTimeRange $rampTimeRange \
		       -description "$plane plane steering" -sectorCount $sectorCount -booster 1} result] {
	    SetStatus "error in writing config.$plane $result"
	    return
	}
       
        catch {exec sddscollapse $filename $filename.collapsed}
	#compute irm
	if [catch {APSBoosterGenerateOrbCorrFiles -configFile $Sector/config.$plane -rootname $rootname \
		       -referenceMatrix $matrixDir/refMatrices/${plane}.default \
		       -singularValues $singularValues -plane $plane \
		       -outputRoot  $Sector -generate 1 } result] {
	    SetStatus "Error in compute irm for $plane plane: $result"
	    return
	}
	set condNumber [exec sdds2stream -par=ConditionNumber $Sector/irm]
	SetStatus "Done for $plane plane.  Condition number is $condNumber ."
	if [catch {exec sddsprocess $Sector/irm "-redefine=col,%s.$coord,%s,select=B?C?P?" -pipe=out \
		       | sddsconvert -pipe=in $Sector/irm.$plane -del=col,*P1,*P2 } result] {
	    return -code error $result
	}
	if [catch {exec sddsprocess $Sector/config.$plane  "-reprint=par,Plane,[string toupper $plane]" -nowarnings \
		       -reedit=col,Name,%/P1/P1.$coord/%/P2/P2.$coord/ \
		       "-reprint=par,BPM1,$SteeringBPM(${Sector}.${plane}BPM1)" \
		       "-reprint=par,BPM2,$SteeringBPM(${Sector}.${plane}BPM2)" } result] {
	    return -code error $result
	}	
    }
    #combine config and irms
    if [catch {exec sddscombine $Sector/config.h $Sector/config.v $Sector/config -over
	exec sddscombine $Sector/irm.h $Sector/irm.v $Sector/irm -merge -over} result] {
	SetStatus "Error in combining hv config1: $result"
	return
    }
    if [catch {exec sddscombine -merge $Sector/config -pipe=out \
		   | sddsxref -pipe $mainDir/hvdefinitions -match=Name=SymbolicName \
		   -take=SymbolicName,ControlName \
		   | sddsconvert -pipe=in $Sector/definitions -del=par,* -retain=col,SymbolicName,ControlName } result] {
	SetStatus "Error in creating definition file: $result"
	return
    }
    SetStatus "controllaw files generated for $Sector."
}

proc StartSteeering {args} {
    global mainDir Sector
    

}

set rampTimeRange 160-220
set rampTimeList [exec sddsconvert  /home/helios/oagData/booster/ramps/correctors/lattices/default/HVCorr.ramp \
		      -toPage=1 -pipe=out \
		      | sddsprocess -pipe -clip=1,1 \
		      | sddsprintout -pipe -col=RampTime,format=%.0f -noTitle -noLabels]
set itemList ""
for {set i 0} {$i<[expr [llength $rampTimeList] -1]} {incr i 1} {
    lappend itemList "[lindex $rampTimeList $i]-[lindex $rampTimeList [expr $i+1]]"
}
set rampTimeRange [lindex $itemList 2]
set mainDir /home/helios/oagData/booster/localSteering/lattices/default
set twissFile /home/helios/oagData/booster/localSteering/lattices/default/refMatrices/booster.twi
set matrixDir /home/helios/oagData/booster/orbitControllaw/lattices/default
set singularValues 4
MakeSelectionFrame
set Sector B1C0
SelectBPMandCorrectors

APSFrameGrid .grid -parent .userFrame -xList {x1 x2}
set w1 .userFrame.grid.x1
set w2 .userFrame.grid.x2
APSLabeledEntry .maindir -parent $w1 -label "Output directory:" -textVariable mainDir -width 60
APSComboboxFrame .ramp -parent $w2 -label "Ramp Time Start/End (ms):" -editable 0 \
	    -width 20 -textVariable rampTimeRange -itemList $itemList
APSLabeledEntry .sig -parent $w1 -label "Number of singular Values:" -textVariable singularValues -width 40
APSButton .gen -parent .userFrame -text "Generate" -command Generate -contextHelp "generate booster steering config for selected sector." 

