#!/usr/local/bin/wish # $Id: liveplot 467 2009-12-04 23:06:39Z toby $ set Revision {$Revision: 467 $ $Date: 2009-12-04 23:06:39 +0000 (Fri, 04 Dec 2009) $} bind all {destroy .} # process command line arguments set exitstat 0 set expnam [lindex $argv 0] if {$expnam == ""} {puts "error -- no experiment name"; set exitstat 1} if $exitstat { puts "usage: $argv0 expnam \[hist #\] \[legend\]" destroy . } set program [file tail $argv0] #set program bkgedit if {[lindex $argv 1] == ""} { set hst 1 } else { set hst [lindex $argv 1] } if {[lindex $argv 2] == ""} { set graph(legend) 1 } else { set graph(legend) [lindex $argv 2] } set graph(backsub) 0 if {$tcl_platform(platform) == "windows"} { set graph(printout) 1 set expgui(tcldump) tcldump.exe } else { set graph(printout) 0 set expgui(tcldump) tcldump } # default values set graph(outname) out.ps set graph(outcmd) lpr set xunits {} set yunits {} set graph(chi2) 0 set graph(xunits) 0 set graph(yunits) 0 set graph(autoraise) 1 set graph(color_diff) blue set graph(color_chi2) magenta set graph(color_bkg) green set graph(color_calc) red set graph(color_obs) black set graph(color_input) magenta set graph(color_fit) blue set expgui(debug) 0 catch {if $env(DEBUG) {set expgui(debug) 1}} #set expgui(debug) 1 set expgui(font) 14 set expgui(lblfontsize) 15 set expgui(fadetime) 10 set expgui(hklbox) 1 set expgui(autotick) 0 set expgui(pixelregion) 5 # location for web pages, if not found locally set expgui(website) www.ncnr.nist.gov/xtal/software/expgui set peakinfo(obssym) scross set peakinfo(obssize) 1.0 set peakinfo(inpsym) triangle set peakinfo(inpsize) 1.0 # create a set of markers for each phase for {set i 1} {$i < 10} {incr i} { set peakinfo(flag$i) 0 set peakinfo(max$i) Inf set peakinfo(min$i) -Inf set peakinfo(dashes$i) 1 } if [catch {package require BLT} errmsg] { tk_dialog .err "BLT Error" "Error -- Unable to load the BLT package" \ error 0 Quit destroy . } # handle Tcl/Tk v8+ where BLT is in a namespace # use the command so that it is loaded catch {blt::graph} catch { namespace import blt::graph namespace import blt::vector } # old versions of blt don't report a version number if [catch {set blt_version}] {set blt_version 0} # option for coloring markers: note that GH keeps changing how to do this! # also element -mapped => -show if {$blt_version < 2.3 || $blt_version >= 8.0} { # version 8.0 is ~same as 2.3 set graph(MarkerColorOpt) -fg # mapped is needed in 8.0, both are OK in 2.3 set graph(ElementShowOption) "-mapped 1" set graph(ElementHideOption) "-mapped 0" } elseif {$blt_version >= 2.4} { set graph(MarkerColorOpt) -outline set graph(ElementShowOption) "-hide 0" set graph(ElementHideOption) "-hide 1" } else { set graph(MarkerColorOpt) -color set graph(ElementShowOption) "-mapped 1" set graph(ElementHideOption) "-mapped 0" } proc waitmsg {message} { set w .wait # kill any window/frame with this name catch {destroy $w} pack [frame $w] frame $w.bot -relief raised -bd 1 pack $w.bot -side bottom -fill both frame $w.top -relief raised -bd 1 pack $w.top -side top -fill both -expand 1 label $w.msg -justify left -text $message -wrap 3i catch {$w.msg configure -font \ -Adobe-Times-Medium-R-Normal--*-180-*-*-*-*-*-* } pack $w.msg -in $w.top -side right -expand 1 -fill both -padx 3m -pady 3m label $w.bitmap -bitmap info pack $w.bitmap -in $w.top -side left -padx 3m -pady 3m update } proc donewaitmsg {} { catch {destroy .wait} update } waitmsg "Loading histogram, Please wait" #-------------------------------------------------------------- # define constants array set peakinfo { color1 magenta color2 cyan color3 yellow color4 sienna color5 orange color6 DarkViolet color7 HotPink color8 salmon color9 LimeGreen } set cycle -1 set modtime 0 #---------------------------------------------------------------- # where are we? set expgui(script) [info script] # translate links -- go six levels deep foreach i {1 2 3 4 5 6} { if {[file type $expgui(script)] == "link"} { set link [file readlink $expgui(script)] if { [file pathtype $link] == "absolute" } { set expgui(script) $link } { set expgui(script) [file dirname $expgui(script)]/$link } } else { break } } # fixup relative paths if {[file pathtype $expgui(script)] == "relative"} { set expgui(script) [file join [pwd] $expgui(script)] } set expgui(scriptdir) [file dirname $expgui(script) ] set expgui(gsasdir) [file dirname $expgui(scriptdir)] set expgui(gsasexe) [file join $expgui(gsasdir) exe] set expgui(docdir) [file join $expgui(scriptdir) doc] # called by a trace on expgui(lblfontsize) proc setfontsize {a b c} { global expgui graph catch { font config lblfont -size [expr -$expgui(lblfontsize)] # this forces a redraw of the plot by changing the title to itself .g configure -title [.g cget -title] } } # define a font used for labels if {$tcl_version >= 8.0} { font create lblfont -family Helvetica -size [expr -$expgui(lblfontsize)] trace variable expgui(lblfontsize) w setfontsize } proc readdata {box} { global expgui modtime expnam if [catch { set modtime [file mtime $expnam.EXP] set loadtime [time { if {$expgui(tcldump) == ""} { readdata_hst $box } else { readdata_tcl $box } }] if $expgui(debug) { tk_dialog .time "Timing info" \ "Histogram loading took $loadtime" "" 0 OK } } errmsg] { if $expgui(debug) { catch {console show} error $errmsg } $box config -title "Read error" tk_dialog .err "Read Error" "Read Error -- $errmsg" \ error 0 OK update } $box element show [lsort -decreasing [$box element show]] global program if {$program == "bkgedit"} bkghstInit } proc readdata_hst {box} { global expgui expnam reflns global lasthst global hst peakinfo xunits $box config -title "(Histogram update in progress)" update # parse the output of a file set lasthst $hst ########################################################################### # set input [open histdump.inp w] # puts $input "$hst" # close $input # set input [open "| $expgui(gsasexe)/hstdump $expnam < histdump.inp" w+] ########################################################################### # use histdmp for histogram info set input [open histdump$hst.inp w] puts $input "$expnam" puts $input "L" puts $input "$hst" puts $input "0" close $input # use hstdmp without an experiment name so that output # is not sent to the .LST file set input [open "| $expgui(gsasexe)/hstdmp < histdump$hst.inp" r] # initalize arrays set num -1 set xlist {} set obslist {} set calclist {} set bcklist {} set xunits {} # define a list of reflection positions for each phase for {set i 1} {$i < 10} {incr i} { set reflns($i) {} } set i 0 while {[gets $input line] >= 0} { incr i # run update every 50th line if {$i > 50} {set i 0; update} if [scan $line %d num] { if {$num > 0} { set Ispec 0 set X -999 scan [string range $line 8 end] %e%e%e%e%e%e \ X Iobs Icalc Ispec fixB fitB #puts $line # eliminate excluded points if {$Ispec > 0.0 && $X >= 0} { lappend xlist $X lappend obslist $Iobs lappend calclist $Icalc lappend bcklist [expr $fixB + $fitB] } # add peaks to peak lists # puts "[string range $line 6 6]" # is this 6 or 7; 6 on win & 7 on SGI if [regexp {[1-9]} [string range $line 6 7] ph] { lappend reflns($ph) $X } } } else { regexp {Time|Theta|keV} $line xunits } } if {$xunits == "Theta"} {set xunits "2-Theta"} close $input catch {file delete histdump$hst.inp} xvec set $xlist obsvec set $obslist calcvec set $calclist bckvec set $bcklist diffvec set [obsvec - calcvec] global obsvec calcvec diffvec set maxdiff [set diffvec(max)] set cmin [set calcvec(min)] set omin [set obsvec(min)] set cmax [set calcvec(max)] set omax [set obsvec(max)] set expgui(min) [expr $omin < $cmin ? $omin : $cmin] set expgui(max) [expr $omax > $cmax ? $omax : $cmax] set ymin1 [expr $cmin - 1.1*$maxdiff] set ymin2 [expr $omin - 1.1*$maxdiff] if {$ymin1 < $ymin2} { diffvec set [diffvec + $ymin1] } { diffvec set [diffvec + $ymin2] } plotdata } proc readdata_tcl {box} { global expgui expnam reflns global lasthst graph global hst peakinfo xunits yunits $box config -title "(Histogram update in progress)" update # parse the output of a file set lasthst $hst # use tcldump set input [open histdump$hst.inp w] puts $input "$hst" # x units -- native puts $input "$graph(xunits)" # y units -- native puts $input "$graph(yunits)" # format (if implemented someday) puts $input "0" close $input # initalize arrays set X {} set OBS {} set CALC {} set BKG {} set WGT {} global refhkllist refphaselist refpos set refpos {} set refhkllist {} set refphaselist {} for {set i 1} {$i < 10} {incr i} { set reflns($i) {} } eval [exec $expgui(tcldump) $expnam < histdump$hst.inp] catch {file delete histdump$hst.inp} if {$X == ""} { $box config -title "(Error reading Histogram $hst)" foreach elem [$box element show] { eval $box element config $elem $graph(ElementHideOption) } return } foreach elem [$box element names] { eval $box element config $elem $graph(ElementShowOption) } xvec set $X obsvec set $OBS calcvec set $CALC bckvec set $BKG refposvec set $refpos diffvec set [obsvec - calcvec] if {$graph(chi2)} { wifdvec set $WGT wifdvec set [wifdvec * diffvec] wifdvec set [wifdvec * diffvec] # now do a running sum set sum 0 set sumlist {} foreach n [wifdvec range 0 end] { set sum [expr $sum + $n] lappend sumlist $sum } wifdvec set $sumlist wifdvec set [wifdvec / [wifdvec length]] } if $graph(backsub) { obsvec set [obsvec - bckvec] calcvec set [calcvec - bckvec] } global obsvec calcvec diffvec set maxdiff [set diffvec(max)] set cmin [set calcvec(min)] set omin [set obsvec(min)] set cmax [set calcvec(max)] set omax [set obsvec(max)] set expgui(min) [expr $omin < $cmin ? $omin : $cmin] set expgui(max) [expr $omax > $cmax ? $omax : $cmax] set ymin1 [expr $cmin - 1.1*$maxdiff] set ymin2 [expr $omin - 1.1*$maxdiff] if {$ymin1 < $ymin2} { diffvec set [diffvec + $ymin1] } { diffvec set [diffvec + $ymin2] } plotdata } proc lblhkl {plot x} { global blt_version expgui tcl_platform tcl_version global refhkllist refphaselist peakinfo refpos # look for peaks within pixelregion pixels or the entire plot range if {$x == "all"} { foreach {xmin xmax} [$plot xaxis limits] {} } else { set xmin [$plot xaxis invtransform [expr $x - $expgui(pixelregion)]] set xmax [$plot xaxis invtransform [expr $x + $expgui(pixelregion)]] } set peaknums [refposvec search $xmin $xmax] set peaklist {} # create a box, if needed if {$expgui(hklbox)} { catch { toplevel .hkl text .hkl.txt -width 30 -height 10 -wrap none \ -yscrollcommand ".hkl.yscroll set" scrollbar .hkl.yscroll -command ".hkl.txt yview" grid .hkl.txt -column 0 -row 1 -sticky nsew grid .hkl.yscroll -column 1 -row 1 -sticky ns grid columnconfigure .hkl 0 -weight 1 grid rowconfigure .hkl 1 -weight 1 wm title .hkl "Liveplot HKL Labels" wm iconname .hkl HKL .hkl.txt insert end "Phase\thkl\tPosition" } } set xcen 0 set lbls 0 foreach peak $peaknums { # put all hkls, all phases in the box if {$expgui(hklbox)} { catch { .hkl.txt insert end "\n[lindex $refphaselist $peak]" .hkl.txt insert end "\t[lindex $refhkllist $peak]" .hkl.txt insert end "\t[lindex $refpos $peak]" .hkl.txt see end } } # label phases with tick marks if [set peakinfo(flag[lindex $refphaselist $peak])] { set pos [refposvec range $peak $peak] if {$lbls <= 0} { set xcen $pos set peaklist [lindex $refhkllist $peak] set lbls 1 } elseif {abs($xcen/$lbls-$pos) <= $expgui(pixelregion)} { set xcen [expr $xcen + $pos] lappend peaklist [lindex $refhkllist $peak] incr lbls } else { puthkllbl $plot $peaklist $xcen $lbls set xcen $pos set peaklist [lindex $refhkllist $peak] set lbls 1 } } } puthkllbl $plot $peaklist $xcen $lbls } proc puthkllbl {plot peaklist xcen lbls} { global blt_version tcl_platform tcl_version expgui if {$peaklist == ""} return set xcen [expr $xcen / $lbls] # avoid bug in BLT 2.3 where Inf does not work for text markers if {$blt_version == 2.3} { set ycen [lindex [$plot yaxis limits] 1] } else { set ycen Inf } # older BLT versions can't rotate text in windows if {$tcl_platform(platform) == "windows" && \ ($blt_version <= 2.3 || $blt_version == 8.0)} { regsub -all { } $peaklist "\n" peaklist set mark [$plot marker create text -coords "$xcen $ycen" \ -text $peaklist -anchor n -bg "" -name hkl$xcen] } else { set mark [$plot marker create text -coords "$xcen $ycen" \ -rotate 90 -text $peaklist -anchor n -bg "" -name hkl$xcen] } if {$tcl_version >= 8.0} { $plot marker config hkl$xcen -font lblfont } if {$expgui(fadetime) > 0} { catch { after [expr $expgui(fadetime) * 1000 ] \ "catch \{ $plot marker delete $mark \}" } } } proc delallhkllbl {plot} { catch { eval $plot marker delete [$plot marker names hkl*] } } proc plotdata {} { global expnam hst peakinfo xunits yunits cycle reflns modtime global lasthst graph expgui box # is there a new histogram to load? if {$hst != $lasthst} { xvec set {} xvec notify now set cycle -1 set modtime 0 $box config -title "Please wait: loading histogram $hst" update return } $box config -title "$expnam cycle $cycle Hist $hst" $box xaxis config -title $xunits $box yaxis config -title $yunits setlegend $box $graph(legend) # reconfigure the data $box element configure 3 \ -symbol $peakinfo(obssym) -color $graph(color_obs) \ -pixels [expr 0.125 * $peakinfo(obssize)]i $box element config 0 -color $graph(color_chi2) $box element config 1 -color $graph(color_bkg) $box element config 2 -color $graph(color_calc) $box element config 4 -color $graph(color_diff) global program if {$program == "bkgedit"} { $box element config 12 -color $graph(color_input) \ -pixels [expr 0.125 * $peakinfo(inpsize)]i \ -symbol $peakinfo(inpsym) $box element config 11 -color $graph(color_fit) } xvec notify now obsvec notify now calcvec notify now bckvec notify now diffvec notify now wifdvec notify now # now deal with peaks for {set i 1} {$i < 10} {incr i} { if {$expgui(autotick)} { set div [expr ( $expgui(max) - $expgui(min) )/40.] set ymin [expr $expgui(min) - ($i+1) * $div] set ymax [expr $expgui(min) - $i * $div] } else { set ymin $peakinfo(min$i) set ymax $peakinfo(max$i) } set j 0 if [set peakinfo(flag$i)] { foreach X $reflns($i) { incr j catch { $box marker create line -name peaks${i}_$j } $box marker config peaks${i}_$j -under 1 \ -coords "$X $ymin $X $ymax" catch { $box marker config peaks${i}_$j \ $graph(MarkerColorOpt) [list $peakinfo(color$i)] if $peakinfo(dashes$i) { $box marker config peaks${i}_$j -dashes "5 5" } } } catch {$box element create phase$i} catch { $box element config phase$i -color $peakinfo(color$i) } } else { eval $box marker delete [$box marker names peaks${i}_*] eval $box element delete [$box element names phase$i] } } # force an update of the plot as BLT may not $box config -title [$box cget -title] update } proc setlegend {box legend} { global blt_version if {$blt_version >= 2.3 && $blt_version < 8.0} { if $legend { $box legend config -hide no } else { $box legend config -hide yes } } else { if $legend { $box legend config -mapped yes } else { $box legend config -mapped no } } } proc minioptionsbox {num} { global blt_version tcl_platform peakinfo expgui set bx .opt$num catch {destroy $bx} toplevel $bx wm iconname $bx "Phase $num options" wm title $bx "Phase $num options" set i $num pack [label $bx.0 -text "Phase $i reflns" ] -side top pack [checkbutton $bx.1 -text "Show reflections" \ -variable peakinfo(flag$i)] -side top # remove option that does not work if {$blt_version != 8.0 || $tcl_platform(platform) != "windows"} { pack [checkbutton $bx.2 -text "Use dashed line" \ -variable peakinfo(dashes$i)] -side top } if !$expgui(autotick) { pack [frame $bx.p$i -bd 2 -relief groove] -side top # pack [checkbutton $bx.p$i.0 -text "Show phase $i reflns" \ # -variable peakinfo(flag$i)] -side left -anchor w pack [label $bx.p$i.1 -text " Y min:"] -side left pack [entry $bx.p$i.2 -textvariable peakinfo(min$i) -width 5] \ -side left pack [label $bx.p$i.3 -text " Y max:"] -side left pack [entry $bx.p$i.4 -textvariable peakinfo(max$i) -width 5] \ -side left } pack [frame $bx.c$i -bd 2 -relief groove] -side top pack [label $bx.c$i.5 -text " color:"] -side left pack [entry $bx.c$i.6 -textvariable peakinfo(color$i) -width 12] \ -side left pack [button $bx.c$i.2 -bg $peakinfo(color$i) -state disabled] -side left pack [button $bx.c$i.1 -text "Color\nmenu" \ -command "setcolor $i"] -side left pack [frame $bx.b] -side top #pack [button $bx.b.1 -command plotdata -text "Update Plot"] \ # -side left pack [button $bx.b.4 -command "destroy $bx" -text Close ] -side right } proc setcolor {num} { global peakinfo set color [tk_chooseColor -initialcolor $peakinfo(color$num) -title "Choose color"] if {$color == ""} return set peakinfo(color$num) $color } proc makepostscriptout {} { global graph box if !$graph(printout) { set out [open "| $graph(outcmd) >& liveplot.msg" w] catch { puts $out [$box postscript output -landscape 1 \ -decorations no -height 7.i -width 9.5i] close $out } msg catch { set out [open liveplot.msg r] if {$msg != ""} {append msg "\n"} append msg [read $out] close $out catch {file delete liveplot.msg} } if {$msg != ""} { tk_dialog .msg "file created" \ "Postscript file processed with command \ $graph(outcmd). Result: $msg" "" 0 OK } else { tk_dialog .msg "file created" \ "Postscript file processed with command \ $graph(outcmd)" "" 0 OK } } else { $box postscript output $graph(outname) -landscape 1 \ -decorations no -height 7.i -width 9.5i tk_dialog .msg "file created" \ "Postscript file $graph(outname) created" "" 0 OK } } proc setprintopt {page} { global graph if $graph(printout) { $page.4.1 config -fg black $page.4.2 config -fg black -state normal $page.6.1 config -fg #888 $page.6.2 config -fg #888 -state disabled } else { $page.4.1 config -fg #888 $page.4.2 config -fg #888 -state disabled $page.6.1 config -fg black $page.6.2 config -fg black -state normal } } proc setpostscriptout {} { global graph tcl_platform set box .out catch {destroy $box} toplevel $box focus $box wm title $box "Set PS options" pack [frame $box.4] -side top -anchor w -fill x pack [checkbutton $box.4.a -text "Write PostScript files" \ -variable graph(printout) -offvalue 0 -onvalue 1 \ -command "setprintopt $box"] -side left -anchor w pack [entry $box.4.2 -textvariable graph(outname)] -side right -anchor w pack [label $box.4.1 -text "PostScript file name:"] -side right -anchor w pack [frame $box.6] -side top -anchor w -fill x pack [checkbutton $box.6.a -text "Print PostScript files" \ -variable graph(printout) -offvalue 1 -onvalue 0 \ -command "setprintopt $box" ] -side left -anchor w pack [entry $box.6.2 -textvariable graph(outcmd)] -side right -anchor w pack [label $box.6.1 -text "Command to print files:"] -side right -anchor w pack [button $box.a -text "Close" -command "destroy $box"] -side top if {$tcl_platform(platform) == "windows"} { set graph(printout) 1 $box.4.a config -state disabled $box.6.a config -fg #888 -state disabled } setprintopt $box } proc setlblopts {} { global expgui tcl_platform tcl_version set box .out catch {destroy $box} toplevel $box focus $box wm title $box "Set hkl options" pack [frame $box.c] -side top -anchor w pack [label $box.c.l -text "HKL label\nerase time:"] -side left pack [entry $box.c.e -textvariable expgui(fadetime) -width 8] \ -side left pack [label $box.c.l1 -text seconds] -side left pack [frame $box.d] -side top -anchor w pack [label $box.d.l -text "HKL label size:"] -side left pack [entry $box.d.e -textvariable expgui(lblfontsize) -width 4] \ -side left pack [label $box.d.l1 -text pixels] -side left # old versions if tcl/tk don't support the font command if {$tcl_version < 8.0} { $box.d.l config -fg #888 $box.d.e config -fg #888 -state disabled $box.d.l1 config -fg #888 } pack [frame $box.f] -side top -anchor w pack [label $box.f.l -text "HKL search region:"] -side left pack [entry $box.f.e -textvariable expgui(pixelregion) -width 3] \ -side left pack [label $box.f.l1 -text pixels] -side left pack [frame $box.e] -side top -anchor w pack [checkbutton $box.e.b -text "Separate window for HKL labels"\ -variable expgui(hklbox)] -side left pack [button $box.a -text "Close" -command "destroy $box"] -side top } proc getsymopts {"sym obs"} { global expgui peakinfo set box .out catch {destroy $box} toplevel $box focus $box wm title .out "set $sym symbol" pack [frame $box.d] -side left -anchor n pack [label $box.d.t -text "Symbol type"] -side top set expgui(sym) $peakinfo(${sym}sym) set expgui(size) $peakinfo(${sym}size) foreach symbol {square circle diamond triangle plus cross \ splus scross} \ symbol_name {square circle diamond triangle plus cross \ thin-plus thin-cross} { pack [radiobutton $box.d.$symbol \ -text $symbol_name -variable expgui(sym) \ -value $symbol] -side top -anchor w } pack [frame $box.e] -side left -anchor n -fill y pack [label $box.e.l -text "Symbol Size"] -side top pack [scale $box.e.s -variable expgui(size) \ -from .1 -to 3 -resolution 0.05] -side top pack [frame $box.a] -side bottom pack [button $box.a.1 -text "Apply" -command "setsymopts $sym"] -side left pack [button $box.a.2 -text "Close" -command "destroy $box"] -side left } proc setsymopts {sym} { global peakinfo expgui if {$peakinfo(${sym}sym) != $expgui(sym)} {set peakinfo(${sym}sym) $expgui(sym)} if {$peakinfo(${sym}size) != $expgui(size)} {set peakinfo(${sym}size) $expgui(size)} } # save some of the global options in ~/.gsas_config proc SaveOptions {} { global graph expgui peakinfo set fp [open [file join ~ .gsas_config] a] foreach v {printout legend outname outcmd autoraise chi2} { puts $fp "set graph($v) $graph($v)" } foreach v {diff chi2 bkg calc obs input fit} { puts $fp "set graph(color_$v) $graph(color_$v)" } foreach v {font lblfontsize fadetime hklbox pixelregion autotick} { puts $fp "set expgui($v) $expgui($v)" } foreach v {obssym obssize inpsym inpsize} { puts $fp "set peakinfo($v) $peakinfo($v)" } close $fp } proc aboutliveplot {} { global Revision tk_dialog .warn About " GSAS\n\ A. C. Larson and\n R. B. Von Dreele,\n LANSCE, Los Alamos\n\n\ LIVEPLOT\nB. Toby, NIST\nNot subject to copyright\n\n\ $Revision\n\ " {} 0 OK } proc getcycle {} { global expnam set cycle -1 catch { set fp [open $expnam.EXP r] set text [read $fp] close $fp regexp {GNLS RUN.*Total cycles run *([0-9]*) } $text x cycle } return $cycle } proc updateifnew {} { global cycle modtime expnam env tcl_platform graph # has the .EXP file been changed? if {[file mtime $expnam.EXP] != $modtime} { # are we in windows and are "locked?" If not, OK to update if {$tcl_platform(platform) == "windows" && [file exists expgui.lck]} { .g config -title "(Experiment directory locked)" } else { set modtime [file mtime $expnam.EXP] set newcycle [getcycle] if {$newcycle != $cycle} { set cycle $newcycle readdata .g } if {$tcl_platform(platform) == "windows" && $graph(autoraise)} { # raise does not seem to be global in Windows, # but this works in Win-95 # nothing seems to work in Win-NT wm withdraw . wm deiconify . } elseif {$graph(autoraise)} { raise . } } } # check again in a second after 1000 updateifnew } proc plotdataupdate {array element action} { global box peakinfo reflns graph # parse the element regexp {([a-z]*)([0-9]*)} $element junk var num if {$var == "color"} { if {$peakinfo($element) == ""} return if [catch { .opt$num.c$num.2 config -bg $peakinfo($element) } ] return set i $num set j 0 if [set peakinfo(flag$i)] { catch { $box element config phase$i -color $peakinfo(color$i) } foreach X $reflns($i) { incr j catch { $box marker config peaks${i}_$j \ $graph(MarkerColorOpt) [list $peakinfo(color$i)] } } } return } waitmsg {Updating} plotdata donewaitmsg } proc ShowCumulativeChi2 {} { global graph box if $graph(chi2) { eval $box y2axis config $graph(ElementShowOption) eval $box element config 0 $graph(ElementShowOption) -label "Chi2" set cycle [getcycle] readdata .g } else { eval $box element config 0 $graph(ElementHideOption) eval $box y2axis config $graph(ElementHideOption) $box element config 0 -label "" } } # evaluate the Chebyshev polynomial with coefficients A at point x # coordinates are rescaled from $xmin=-1 to $xmax=1 proc chebeval {A x xmin xmax} { set xs [expr {-1 + 2 * (1.*$x - $xmin) / (1.*$xmax - 1.*$xmin)}] set Tpp 0 set Tp 0 set total 0 foreach a $A { if {$Tpp == $Tp && $Tp == 0} { set T 1 } elseif {$Tpp == 0} { set T $xs } else { set T [expr {2. * $xs * $Tp - $Tpp}] } set total [expr {$total + $a * $T}] set Tpp $Tp set Tp $T } return $total } # determine a very approximate set of Chebyshev coefficients of order n # to compute Y from X (fast but not very good) proc chebgen {X Y xmin xmax n} { if {[llength $X] != [llength $Y]} return set xnorm [expr {2. / ($xmax - $xmin)}] set pi [expr {2*asin(1)}] set a(0) 0. for {set i 1} {$i < $n} {incr i} {set a($i) 0.} foreach x1 $X x2 [lrange $X 1 end] y1 $Y y2 [lrange $Y 1 end] { if {$x2 == ""} break set xs1 [expr {-1 + ($x1 - $xmin) * $xnorm}] set th1 [expr {acos(-1 + ($x1 - $xmin) * $xnorm)}] set xs2 [expr {-1 + ($x2 - $xmin) * $xnorm}] set th2 [expr {acos(-1 + ($x2 - $xmin) * $xnorm)}] set thbar [expr {($th1 + $th2)/2.}] set dth [expr {$th1 - $th2}] set xsbar [expr {cos($thbar)}] set ybar [expr {($xsbar - $xs1) / ($xs2 - $xs1) * ($y2 - $y1) + $y1}] # seems to work better starting with just 2 terms # for {set i 0} {$i < $n} {incr i} for {set i 0} {$i < 2} {incr i} { set a($i) [expr {$a($i) + $ybar * cos($i*$thbar) * $dth}] } } set A [expr {$a(0) / $pi}] for {set i 1} {$i < $n} {incr i} { lappend A [expr {2 * $a($i) / $pi}] } return $A } # disable the improve fit button proc bkgResetFit {} { .bkg.f.fit2 config -state disabled } # enable the improve fit button, if appropriate proc bkgMoreFit {} { global cheblist if {[llength $cheblist] < 2} {bkgResetFit;return} .bkg.f.fit2 config -state normal } # perform a Gauss-Newton fit to optimize Chebyshev coefficients A proc chebGN {X Y S A xmin xmax "damp 0.75"} { # Gauss-Newton if {[llength $X] != [llength $Y]} return set xnorm [expr {2. / ($xmax - $xmin)}] # denominator set sum2 0. foreach x $X s $S { set xs [expr {-1 + (1.*$x - $xmin) * $xnorm}] set Tpp 0 set Tp 0 foreach a1 $A { if {$Tpp == $Tp && $Tp == 0} { set T 1 } elseif {$Tpp == 0} { set T $xs } else { set T [expr {2. * $xs * $Tp - $Tpp}] } set sum2 [expr {$sum2 + $T /($s*$s)}] set Tpp $Tp set Tp $T } } # Evaluate Ycalc & sum(delta2) set sumd2 0. foreach x $X y $Y { # set xs [expr {-1 + (1.*$x - $xmin) * $xnorm}] lappend Ycalc [set yc [chebeval $A $x $xmin $xmax]] set sumd2 [expr {$sumd2 + ($y - $yc)*($y - $yc)}] } set k -1 foreach a $A {incr k; set sum($k) 0} foreach x $X y $Y yc $Ycalc s $S { set xs [expr {-1 + (1.*$x - $xmin) * $xnorm}] set Tpp 0 set Tp 0 set k -1 foreach a $A { incr k if {$Tpp == $Tp && $Tp == 0} { set T 1 } elseif {$Tpp == 0} { set T $xs } else { set T [expr {2. * $xs * $Tp - $Tpp}] } set sum($k) [expr {$sum($k) + ($T * ($yc - $y))/($s*$s)}] set Tpp $Tp set Tp $T } } set sumd2r $sumd2 set d $damp # compute new cheb terms while {$d > $damp/32} { set k -1 set Anew {} foreach a $A { incr k lappend Anew [expr {$a - $d*($sum($k) / $sum2)}] } # Evaluate new Ycalc & sum(delta2) set sumd2r 0. foreach x $X y $Y { # set xs [expr {-1 + (1.*$x - $xmin) * $xnorm}] set yc [chebeval $Anew $x $xmin $xmax] set sumd2r [expr {$sumd2r + ($y - $yc)*($y - $yc)}] } # are these shifts an improvement? if {$sumd2r < $sumd2} { # are we converged? if {[expr {($sumd2-$sumd2r)/$sumd2}] < 0.0001} {return ""} return $Anew } set d [expr {$d/2.}] } return "" } # change the binding of the mouse, based on the selected mode proc bkgEditMode {b} { global zoomcommand box # get binding set bindtag $box catch { if {[bind bltZoomGraph] != ""} { set bindtag bltZoomGraph } } # save the zoom command if [catch {set zoomcommand}] { set zoomcommand [bind $bindtag <1>] .bkg.f.fit1 config -state disabled .bkg.f.fit2 config -state disabled .bkg.f.terms config -state disabled } foreach c {1 2 3} { if {$c == $b} { .bkg.l.b$c config -relief sunken } else { .bkg.l.b$c config -relief raised } } # reset previous mode; if in the middle if {[string trim [bind $box ]] != ""} { blt::ResetZoom $box } if {$b == 2} { bind $bindtag <1> "bkgAddPoint %x %y" .g config -cursor arrow } elseif {$b == 3} { bind $bindtag <1> "bkgDelPoint %x %y" .g config -cursor circle } else { bind $bindtag <1> $zoomcommand .g config -cursor crosshair } } # plot the background points proc bkgPointPlot {} { global bkglist termmenu chebterms expnam hst tmin tmax set l {} set fp [open $expnam.bkg$hst w] puts $fp "y p h e $hst b ! fixed background points for use in BKGEDIT" foreach p $bkglist { puts $fp "i\t$p\t0.0" append l " $p" } if {[llength $bkglist] > 0} { puts $fp "i\t[expr $tmin*0.99] [lindex [lindex $bkglist 0] 1]\t0.0" puts $fp "i\t[expr $tmax*1.01] [lindex [lindex $bkglist end] 1]\t0.0" } close $fp .g element config 12 -data $l if {[set l [llength $bkglist]] > 3} { .bkg.f.fit1 config -state normal .bkg.f.terms config -state normal $termmenu delete 0 end set imax {} for {set i 2} {$i <= $l/1.5} {incr i 2} { $termmenu insert end radiobutton -label $i \ -variable chebterms -command {bkgMoreFit} set imax $i } if {$imax < $chebterms} {set chebterms $imax} } else { .bkg.f.fit1 config -state disabled .bkg.f.fit2 config -state disabled .bkg.f.terms config -state disabled set chebterms 2 } } # add a bkg point at screen coordinates x,y proc bkgAddPoint {x y} { global bkglist tmin tmax set xy [.g invtransform $x $y] set x [lindex $xy 0] if {$x < $tmin} {set x $tmin} if {$x > $tmax} {set x $tmax} lappend bkglist [list $x [lindex $xy 1]] set bkglist [lsort -real -index 0 $bkglist] bkgMoreFit bkgFillPoints bkgPointPlot } # delete the bkg point closest to screen coordinates x,y proc bkgDelPoint {x y} { global bkglist set closest {} set dist2 {} set i -1 foreach p $bkglist { incr i set sxy [eval .g transform $p] if {$closest == ""} { set closest $i set dist2 0 foreach v1 $sxy v2 "$x $y" { set dist2 [expr {$dist2 + ($v1 - $v2)*($v1 - $v2)}] } } else { set d2 0 foreach v1 $sxy v2 "$x $y" { set d2 [expr {$d2 + ($v1 - $v2)*($v1 - $v2)}] } if {$d2 < $dist2} { set closest $i set dist2 $d2 } } } set bkglist [lreplace $bkglist $closest $closest] bkgMoreFit bkgPointPlot bkgFillPoints } # initialize the background plot proc bkghstInit {} { global bkglist tmin tmax hst expnam cheblist chebterms set tmin [histinfo $hst tmin] set tmax [histinfo $hst tmax] if {[catch {expr $tmin}] || [catch {expr $tmax}]} { tk_dialog .err "MIN/MAX Error" "Error -- Unable read tmin or tmax (has POWPREF been run?" \ error 0 Quit destroy . } set bkglist {} if [file exists $expnam.bkg$hst] { catch { set fp [open $expnam.bkg$hst r] gets $fp line while {[gets $fp line]>=0} { set x [lindex $line 1] set y [lindex $line 2] if {$x >= $tmin && $x <= $tmax} { lappend bkglist [list $x $y] } } } close $fp } bkgEditMode 1 bkgPointPlot bkgFillPoints set cheblist "" bkgResetFit BkgFillCheb set chebterms 2 } # fit a Chebyshev polynomial to the selected background points proc bkgFit {termlist button} { global bkglist chebterms cheblist $button config -relief sunken update foreach p $bkglist { lappend S 1. foreach v $p var {X Y} { lappend $var $v } } global tmin tmax if {[llength $termlist] < 2} { # get a starting point set termlist [chebgen $X $Y $tmin $tmax $chebterms] # plot it set calcb {} foreach x [xvec range 0 end] { lappend calcb [chebeval $termlist $x $tmin $tmax] } .g element configure 11 -xdata xvec -ydata $calcb update } elseif {[llength $termlist] < $chebterms} { while {[llength $termlist] < $chebterms} { lappend termlist 0. } } elseif {[llength $termlist] > $chebterms} { set termlist [lrange $termlist 0 [expr $chebterms -1]] } # iterate for {set i 1} {$i < 20} {incr i} { set termlist1 [chebGN $X $Y $S $termlist $tmin $tmax] # have we converged? if {$termlist1 == ""} { bkgResetFit set cheblist $termlist BkgFillCheb bkgFillPoints $button config -relief raised return } set termlist $termlist1 set calcb {} foreach x [xvec range 0 end] { lappend calcb [chebeval $termlist $x $tmin $tmax] } .g element configure 11 -xdata xvec -ydata $calcb update } set cheblist $termlist BkgFillCheb bkgFillPoints bkgMoreFit $button config -relief raised } # put the Chebyshev coefficients into edit widgets proc BkgFillCheb {} { global cheblist global chebedit catch {destroy .bkg.canvas.fr} set top [frame .bkg.canvas.fr] .bkg.canvas create window 0 0 -anchor nw -window $top # delete trace on chebedit foreach v [ trace vinfo chebedit] { eval trace vdelete chebedit $v } if {[llength $cheblist] == 0} { grid [label $top.0 -text "(no terms defined)"] -col 1 -row 1 .bkg.cw config -state disabled } else { set i -1 .bkg.cw config -state normal foreach c $cheblist { incr i grid [frame $top.$i -relief groove -bd 3] -col $i -row 1 grid [label $top.$i.l -text "[expr 1+$i]"] -col 1 -row 1 grid [entry $top.$i.e -textvariable chebedit($i) -width 13] \ -col 2 -row 1 set chebedit($i) $c } trace variable chebedit w "BkgRecalcCheb $top" } update idletasks set sizes [grid bbox $top] .bkg.canvas config -scrollregion $sizes -height [lindex $sizes 3] } # respond to edits made to Chebyshev terms proc BkgRecalcCheb {top var i mode} { global chebedit cheblist if [catch {expr $chebedit($i)}] { $top.$i.e config -fg red } else { $top.$i.e config -fg black set cheblist [lreplace $cheblist $i $i $chebedit($i)] global tmin tmax # plot it set calcb {} foreach x [xvec range 0 end] { lappend calcb [chebeval $cheblist $x $tmin $tmax] } .g element configure 11 -xdata xvec -ydata $calcb update bkgMoreFit } } # put the bkg points into edit widgets proc bkgFillPoints {} { global bkglist tmin tmax bkgedit # delete trace on bkgedit foreach v [ trace vinfo bkgedit] { eval trace vdelete bkgedit $v } catch {destroy .bkg.bc.fr} set top [frame .bkg.bc.fr] .bkg.bc create window 0 0 -anchor nw -window $top if {[llength $bkglist] == 0} { grid [label $top.0 -text "(no points defined)"] -col 1 -row 1 } else { set i -1 foreach p $bkglist { incr i grid [frame $top.$i -relief groove -bd 3] -col $i -row 1 grid [label $top.$i.l -text "[expr 1+$i]"] -col 1 -rowspan 2 -row 1 grid [entry $top.$i.ex -textvariable bkgedit(x$i) -width 13] \ -col 2 -row 1 grid [entry $top.$i.ey -textvariable bkgedit(y$i) -width 13] \ -col 2 -row 2 foreach val $p var {x y} { set bkgedit(${var}$i) $val } } trace variable bkgedit w "BkgRecalcBkg $top" } update idletasks set sizes [grid bbox $top] .bkg.bc config -scrollregion $sizes -height [lindex $sizes 3] } # respond to edits made to bkg points proc BkgRecalcBkg {top var i mode} { global bkgedit bkglist tmin tmax regexp {(.)([0-9]*)} $i junk var num if [catch {expr $bkgedit($i)}] { $top.$num.e$var config -fg red } else { $top.$num.e$var config -fg black set p [lindex $bkglist $num] if {$var == "x"} { set x $bkgedit($i) if {$x < $tmin} {set x $tmin} if {$x > $tmax} {set x $tmax} set bkglist [lreplace $bkglist $num $num \ [list $x [lindex $p 1]]] } else { set bkglist [lreplace $bkglist $num $num \ [list [lindex $p 0] $bkgedit($i)]] } } bkgPointPlot } # save the Chebyshev terms in the .EXP file proc bkgChebSave {} { global hst cheblist expgui Revision expmap expnam histinfo $hst backtype set 1 histinfo $hst backterms set [llength $cheblist] set num 0 foreach v $cheblist { set var "bterm[incr num]" histinfo $hst $var set $v } histinfo $hst bref set 0 # add a history record exphistory add " BKGEDIT [lindex $Revision 1] [lindex $expmap(Revision) 1] -- [clock format [clock seconds]]" # now save the file expwrite $expnam.EXP } source [file join $expgui(scriptdir) gsascmds.tcl] source [file join $expgui(scriptdir) readexp.tcl] source [file join $expgui(scriptdir) opts.tcl] # override options with locally defined values if [file exists [file join $expgui(scriptdir) localconfig]] { source [file join $expgui(scriptdir) localconfig] } if [file exists [file join ~ .gsas_config]] { source [file join ~ .gsas_config] } SetTkDefaultOptions $expgui(font) if [file executable [file join $expgui(gsasexe) $expgui(tcldump)]] { set expgui(tcldump) [file join $expgui(gsasexe) $expgui(tcldump)] # puts "got tcldump" } else { set expgui(tcldump) {} # puts "no tcldump" } # vectors foreach vec {xvec obsvec calcvec bckvec diffvec refposvec wifdvec} { vector $vec $vec notify never } # create the graph if [catch { set box [graph .g -plotbackground white] } errmsg] { tk_dialog .err "BLT Error" \ "BLT Setup Error: could not create a graph (msg: $errmsg). \ There is a problem with the setup of BLT on your system. See the expgui.html file for more info." \ error 0 "Quit" exit } if [catch { Blt_ZoomStack $box } errmsg] { tk_dialog .err "BLT Error" \ "BLT Setup Error: could not access a Blt_ routine (msg: $errmsg). \ The pkgIndex.tcl is probably not loading bltGraph.tcl. See the expgui.html file for more info." \ error 0 "Limp ahead" } # modify zoom so that y2axis is not zoomed in for blt2.4u+ catch { regsub -all y2axis [info body blt::PushZoom] " " b1 proc blt::PushZoom {graph} $b1 } $box element create 0 -xdata xvec -ydata wifdvec -color $graph(color_chi2) \ -line 3 -symbol none -label "Chi2" -mapy y2 $box element create 1 -label bckgr -symbol none $box element config 1 -xdata xvec -ydata bckvec -color $graph(color_bkg) $box element create 3 -color $graph(color_obs) -linewidth 0 -label Obs \ -symbol $peakinfo(obssym) \ -pixels [expr 0.125 * $peakinfo(obssize)]i $box element create 2 -label Calc -color $graph(color_calc) -symbol none $box element create 4 -label diff -color $graph(color_diff) -symbol none if {$program == "liveplot"} { $box y2axis config -min 0 -title {Cumulative Chi Squared} } elseif {$program == "bkgedit"} { eval $box element config 0 $graph(ElementHideOption) eval $box y2axis config $graph(ElementHideOption) $box element config 0 -label "" eval $box element config 1 $graph(ElementHideOption) $box element config 1 -label "" eval $box element config 4 $graph(ElementHideOption) $box element config 4 -label "" $box element create 11 $box element create 12 $box element configure 12 -color $graph(color_input) \ -pixels [expr 0.125 * $peakinfo(inpsize)]i \ -line 0 -symbol $peakinfo(inpsym) -label "bkg pts" $box element configure 11 -color $graph(color_fit) \ -symbol none -label "Cheb fit" -dashes 5 -line 2 $box element show "3 2 11 12" } $box element config 3 -xdata xvec -ydata obsvec $box element config 2 -xdata xvec -ydata calcvec $box element config 4 -xdata xvec -ydata diffvec if {$expgui(tcldump) != ""} { bind . "lblhkl $box %x" bind . "lblhkl $box %x" bind . "lblhkl $box all" bind . "lblhkl $box all" bind . "delallhkllbl $box" bind . "delallhkllbl $box" if {[bind bltZoomGraph] != ""} { bind bltZoomGraph "lblhkl $box %x" bind bltZoomGraph "delallhkllbl %W" } else { bind $box "lblhkl $box %x" bind $box "delallhkllbl %W" } } else { $box element config 1 -label "" eval $box element config 4 $graph(ElementHideOption) } $box yaxis config -title {} setlegend $box $graph(legend) frame .a -bd 3 -relief groove pack [menubutton .a.file -text File -underline 0 -menu .a.file.menu] -side left menu .a.file.menu .a.file.menu add cascade -label Tickmarks -menu .a.file.menu.tick menu .a.file.menu.tick foreach num {1 2 3 4 5 6 7 8 9} { .a.file.menu.tick add checkbutton -label "Phase $num" \ -variable peakinfo(flag$num) \ -command plotdata } .a.file.menu add cascade -label Histogram -menu .a.file.menu.hist -state disabled .a.file.menu add command -label "Update Plot" \ -command {set cycle [getcycle];readdata .g} .a.file.menu add command -label "Make PostScript" -command makepostscriptout .a.file.menu add command -label Quit -command "destroy ." pack [menubutton .a.options -text Options -underline 0 -menu .a.options.menu] \ -side left menu .a.options.menu .a.options.menu add cascade -label "Configure Tickmarks" -menu .a.options.menu.tick menu .a.options.menu.tick .a.options.menu.tick add radiobutton -label "Manual Placement" \ -value 0 -variable expgui(autotick) -command plotdata .a.options.menu.tick add radiobutton -label "Auto locate" \ -value 1 -variable expgui(autotick) -command plotdata .a.options.menu.tick add separator foreach num {1 2 3 4 5 6 7 8 9} { .a.options.menu.tick add command -label "Phase $num" \ -command "minioptionsbox $num" } if {$program == "liveplot"} { .a.options.menu add command -label "Obs symbol" -command getsymopts } else { .a.options.menu add cascade -label "Symbol Type" -menu .a.options.menu.sym menu .a.options.menu.sym foreach var {obs inp} lbl {Observed "Input bkg"} { .a.options.menu.sym add command -label $lbl -command "getsymopts $var" } } .a.options.menu add cascade -label "Symbol color" -menu .a.options.menu.color menu .a.options.menu.color set l1 {obs calc diff bkg chi2} set l2 {Observed Calculated Obs-Calc Background Cumulative-Chi2} if {$program != "liveplot"} { lappend l1 input fit lappend l2 "Input points" "Cheb. fit" } foreach var $l1 lbl $l2 { .a.options.menu.color add command -label $lbl \ -command "set graph(color_$var) \[tk_chooseColor -initialcolor \$graph(color_$var) -title \"Choose \$lbl color\"]; plotdata" } if {$expgui(tcldump) != "" && $program == "liveplot"} { .a.options.menu add cascade -label "X units" -menu .a.options.menu.xunits menu .a.options.menu.xunits .a.options.menu.xunits add radiobutton -label "As collected" \ -variable graph(xunits) -value 0 \ -command {set cycle [getcycle];readdata .g} .a.options.menu.xunits add radiobutton -label "d-space" \ -variable graph(xunits) -value 1 \ -command {set cycle [getcycle];readdata .g} .a.options.menu.xunits add radiobutton -label "Q" \ -variable graph(xunits) -value 2 \ -command {set cycle [getcycle];readdata .g} .a.options.menu add cascade -label "Y units" -menu .a.options.menu.yunits menu .a.options.menu.yunits .a.options.menu.yunits add radiobutton -label "As collected" \ -variable graph(yunits) -value 0 \ -command {set cycle [getcycle];readdata .g} .a.options.menu.yunits add radiobutton -label "Normalized" \ -variable graph(yunits) -value 1 \ -command {set cycle [getcycle];readdata .g} .a.options.menu add command -label "HKL labeling" -command setlblopts .a.options.menu add checkbutton -label "Subtract background" \ -variable graph(backsub) \ -command {set cycle [getcycle];readdata .g} } else { set graph(xunits) 0 } .a.options.menu add checkbutton -label "Include legend" \ -variable graph(legend) \ -command {setlegend $box $graph(legend)} .a.options.menu add command -label "Set PS output" -command setpostscriptout .a.options.menu add cascade -menu .a.options.menu.font \ -label "Screen font" menu .a.options.menu.font foreach f {10 11 12 13 14 16 18 20 22} { .a.options.menu.font add radiobutton \ -command {SetTkDefaultOptions $expgui(font); ResizeFont .} \ -label $f -value $f -variable expgui(font) -font "Helvetica -$f" } if {$program == "liveplot"} { .a.options.menu add checkbutton -label "Raise on update" \ -variable graph(autoraise) .a.options.menu add checkbutton -label "Cumulative Chi2" \ -variable graph(chi2) -command ShowCumulativeChi2 .a.options.menu add command -label "Save Options" -underline 1 \ -command "SaveOptions" ShowCumulativeChi2 } elseif {$program == "bkgedit"} { catch {pack [frame .bkg -bd 3 -relief sunken] -side bottom -fill both} grid [label .bkg.top -text "Background Point Editing"] \ -col 0 -row 0 -columnspan 4 grid [button .bkg.help -text Help -bg yellow \ -command "MakeWWWHelp liveplot.html bkgedit"] \ -column 5 -row 0 -rowspan 2 -sticky n grid [frame .bkg.l -bd 3 -relief groove] \ -col 0 -row 1 -columnspan 2 -sticky nse grid [label .bkg.l.1 -text "Mouse click\naction"] -col 0 -row 0 foreach c {1 2 3} l {zoom add delete} { grid [button .bkg.l.b$c -text $l -command "bkgEditMode $c"] \ -col $c -row 0 } grid [frame .bkg.f -bd 3 -relief groove] \ -col 3 -row 1 -columnspan 2 -sticky nsw grid [button .bkg.f.fit1 -text "Start\nFit" -command {bkgFit "" .bkg.f.fit1}] \ -col 1 -row 1 grid [button .bkg.f.fit2 -text "Improve\nFit" \ -command {bkgFit $cheblist .bkg.f.fit2}] -col 2 -row 1 grid [label .bkg.f.tl -text "with"] -col 3 -row 1 set termmenu [tk_optionMenu .bkg.f.terms chebterms 0] grid .bkg.f.terms -col 4 -row 1 grid [label .bkg.f.tl1 -text "terms"] -col 5 -row 1 grid [frame .bkg.c1 -bd 3 -relief groove] \ -col 0 -row 5 -rowspan 2 -sticky nsew grid [label .bkg.c1.1 -text "Chebyshev\nterms"] -col 0 -row 0 grid [canvas .bkg.canvas \ -scrollregion {0 0 5000 500} -width 0 -height 0 \ -xscrollcommand ".bkg.scroll set"] \ -column 1 -row 5 -columnspan 3 -sticky nsew grid [scrollbar .bkg.scroll -command ".bkg.canvas xview" \ -orient horizontal] -column 1 -row 6 -columnspan 3 -sticky nsew grid [button .bkg.cw -text "Save in EXP\nfile & Exit" \ -command "bkgChebSave;exit"] \ -col 4 -columnspan 2 -row 5 -rowspan 2 -sticky ns grid [frame .bkg.bl -bd 3 -relief groove] \ -col 0 -row 3 -rowspan 2 -sticky nsew grid [label .bkg.bl.1 -text "Background\npoints"] -col 0 -row 0 grid [canvas .bkg.bc \ -scrollregion {0 0 5000 500} -width 0 -height 0 \ -xscrollcommand ".bkg.bs set"] \ -column 1 -row 3 -columnspan 5 -sticky nsew grid [scrollbar .bkg.bs -command ".bkg.bc xview" -orient horizontal] \ -column 1 -row 4 -columnspan 5 -sticky nsew grid columnconfigure .bkg 1 -weight 1 grid columnconfigure .bkg 2 -weight 1 grid columnconfigure .bkg 3 -weight 1 grid rowconfigure .bkg 3 -weight 1 grid rowconfigure .bkg 5 -weight 1 .g config -title "" } pack [menubutton .a.help -text Help -underline 0 -menu .a.help.menu] -side right menu .a.help.menu -tearoff 0 .a.help.menu add command -command "MakeWWWHelp liveplot.html" -label "Web page" .a.help.menu add command -command aboutliveplot -label About pack .a -side top -fill both pack $box -fill both -expand yes # add the extra options set fl [file join $expgui(scriptdir) icddcmd.tcl] if [file exists $fl] {source $fl} set fl [file join $expgui(scriptdir) cellgen.tcl] if [file exists $fl] {source $fl} expload $expnam.EXP mapexp # fill the histogram menu if {[llength $expmap(powderlist)] > 1} { .a.file.menu entryconfigure Histogram -state normal menu .a.file.menu.hist if {[llength $expmap(powderlist)] > 15} { set i 0 foreach num [lsort -integer $expmap(powderlist)] { incr i # for now include, but disable histograms set state disabled if {[string range $expmap(htype_$num) 3 3] != "*"} { set state normal } if {$i == 1} { set num1 $num menu .a.file.menu.hist.$num1 } .a.file.menu.hist.$num1 add radiobutton -label $num -value $num \ -variable hst -state $state \ -command {set cycle [getcycle];readdata .g} if {$i >= 10} { set i 0 .a.file.menu.hist add cascade -label "$num1-$num" \ -menu .a.file.menu.hist.$num1 } } if {$i != 0} { .a.file.menu.hist add cascade -label "$num1-$num" \ -menu .a.file.menu.hist.$num1 } } else { foreach num [lsort -integer $expmap(powderlist)] { # for now include, but disable unprocessed histograms set state disabled if {[string range $expmap(htype_$num) 3 3] != "*"} { set state normal } .a.file.menu.hist add radiobutton -label $num -value $num \ -variable hst -state $state \ -command {set cycle [getcycle];readdata .g} } } } updateifnew donewaitmsg trace variable peakinfo w plotdataupdate