source: trunk/liveplot @ 625

Last change on this file since 625 was 563, checked in by toby, 16 years ago

# on 2002/02/11 19:32:02, toby did:
add cursor display (livecursor) -- requested by Lachlan

  • Property rcs:author set to toby
  • Property rcs:date set to 2002/02/11 19:32:02
  • Property rcs:lines set to +30 -2
  • Property rcs:rev set to 1.27
  • Property rcs:state set to Exp
  • Property svn:keywords set to Author Date Revision Id
File size: 65.2 KB
Line 
1#!/usr/local/bin/wish
2# $Id: liveplot 563 2009-12-04 23:08:16Z toby $
3set Revision {$Revision: 563 $ $Date: 2009-12-04 23:08:16 +0000 (Fri, 04 Dec 2009) $}
4
5bind all <Control-KeyPress-c> {destroy .}
6# process command line arguments
7set exitstat 0
8set expnam [lindex $argv 0]
9if {$expnam == ""} {puts "error -- no experiment name"; set exitstat 1}
10if $exitstat {
11    puts "usage: $argv0 expnam \[hist #\] \[legend\]"
12    destroy .
13}
14set program [file tail $argv0]
15#set program bkgedit
16
17if {[lindex $argv 1] == ""} {
18    set hst 1
19} else {
20    set hst [lindex $argv 1]
21}
22if {[lindex $argv 2] == ""} {
23    set graph(legend) 1
24} else {
25    set graph(legend) [lindex $argv 2]
26}
27
28set graph(backsub) 0
29
30if {$tcl_platform(platform) == "windows"} {
31    set graph(printout) 1
32    set expgui(tcldump) tcldump.exe
33} else {
34    set graph(printout) 0
35    set expgui(tcldump) tcldump
36}
37
38# default values
39set graph(outname) out.ps
40set graph(outcmd) lpr
41set xunits {}
42set yunits {}
43set graph(chi2) 0
44set graph(xunits) 0
45set graph(yunits) 0
46set graph(autoraise) 1
47set graph(color_diff) blue
48set graph(color_chi2) magenta
49set graph(color_bkg) green
50set graph(color_obs) black
51set graph(color_input) magenta
52set graph(color_fit) blue
53set expgui(debug) 0
54catch {if $env(DEBUG) {set expgui(debug) 1}}
55#set expgui(debug) 1
56set expgui(font) 14
57set expgui(lblfontsize) 15
58set expgui(fadetime) 10
59set expgui(hklbox) 1
60set expgui(autotick) 0
61set expgui(pixelregion) 5
62# location for web pages, if not found locally
63set expgui(website) www.ncnr.nist.gov/xtal/software/expgui
64set peakinfo(obssym) scross
65if {$program == "bkgedit"}  {
66    set peakinfo(obssize) 0.15
67    set graph(color_calc) pink
68} else {
69    set peakinfo(obssize) 1.0
70    set graph(color_calc) red
71}
72set peakinfo(inpsym) triangle
73set peakinfo(inpsize) 1.0
74# create a set of markers for each phase
75for {set i 1} {$i < 10} {incr i} {
76    set peakinfo(flag$i) 0
77    set peakinfo(max$i) Inf
78    set peakinfo(min$i) -Inf
79    set peakinfo(dashes$i) 1
80    set graph(label$i) Phase$i
81}
82set expgui(RadiiList) {}
83
84proc waitmsg {message} {
85    set w .wait
86    # kill any window/frame with this name
87    catch {destroy $w}
88    pack [frame $w]
89    frame $w.bot -relief raised -bd 1
90    pack $w.bot -side bottom -fill both
91    frame $w.top -relief raised -bd 1
92    pack $w.top -side top -fill both -expand 1
93    label $w.msg -justify left -text $message -wrap 3i
94    catch {$w.msg configure -font \
95                -Adobe-Times-Medium-R-Normal--*-180-*-*-*-*-*-*
96    }
97    pack $w.msg -in $w.top -side right -expand 1 -fill both -padx 3m -pady 3m
98    label $w.bitmap -bitmap info
99    pack $w.bitmap -in $w.top -side left -padx 3m -pady 3m
100    update
101}
102
103proc donewaitmsg {} {
104    catch {destroy .wait}
105    update
106}
107
108waitmsg "Loading histogram, Please wait"
109
110#--------------------------------------------------------------
111# define constants
112array set peakinfo {
113    color1 magenta
114    color2 cyan
115    color3 yellow
116    color4 sienna
117    color5 orange
118    color6 DarkViolet
119    color7 HotPink
120    color8 salmon
121    color9 LimeGreen
122}
123set cycle -1
124set modtime 0
125
126#----------------------------------------------------------------
127# where are we?
128set expgui(script) [info script]
129# translate links -- go six levels deep
130foreach i {1 2 3 4 5 6} {
131    if {[file type $expgui(script)] == "link"} {
132        set link [file readlink $expgui(script)]
133        if { [file  pathtype  $link] == "absolute" } {
134            set expgui(script) $link
135        } {
136            set expgui(script) [file dirname $expgui(script)]/$link
137        }
138    } else {
139        break
140    }
141}
142
143# fixup relative paths
144if {[file pathtype $expgui(script)] == "relative"} {
145    set expgui(script) [file join [pwd] $expgui(script)]
146}
147set expgui(scriptdir) [file dirname $expgui(script) ]
148set expgui(gsasdir) [file dirname $expgui(scriptdir)]
149set expgui(gsasexe) [file join $expgui(gsasdir) exe]
150set expgui(docdir) [file join $expgui(scriptdir) doc]
151
152source [file join $expgui(scriptdir) gsascmds.tcl]
153source [file join $expgui(scriptdir) readexp.tcl]
154source [file join $expgui(scriptdir) opts.tcl]
155
156if {$program == "bkgedit"}  {
157    lappend auto_path $expgui(scriptdir)
158    if {$tcl_version < 8.1} {
159        MyMessageBox -parent . -title "La Load Error" \
160                -message "$program requires Tcl/Tk version 8.1 or higher" \
161                -helplink "expgui.html La" \
162                -icon error -type Exit -default exit
163        exit
164    }
165    if [catch {package require La} errmsg] {
166        MyMessageBox -parent . -title "La Load Error" \
167                -message "Error -- Unable to load the La (Linear Algebra) package; cannot run $program" \
168                -helplink "expgui.html La" \
169                -icon error -type Exit -default exit
170        exit
171    }
172}
173
174if [catch {package require BLT} errmsg] {
175    MyMessageBox -parent . -title "BLT Error" \
176            -message "Error -- Unable to load the BLT package; cannot run $program" \
177            -helplink "expgui.html blt" \
178            -icon error -type Exit -default exit
179    exit
180}
181# handle Tcl/Tk v8+ where BLT is in a namespace
182#  use the command so that it is loaded
183catch {blt::graph}
184catch {
185    namespace import blt::graph
186    namespace import blt::vector
187}
188# old versions of blt don't report a version number
189if [catch {set blt_version}] {set blt_version 0}
190# option for coloring markers: note that GH keeps changing how to do this!
191# also element -mapped => -show
192if {$blt_version < 2.3 || $blt_version >= 8.0} {
193    # version 8.0 is ~same as 2.3
194    set graph(MarkerColorOpt) -fg
195    # mapped is needed in 8.0, both are OK in 2.3
196    set graph(ElementShowOption) "-mapped 1"
197    set graph(ElementHideOption) "-mapped 0"
198} elseif {$blt_version >= 2.4} {
199    set graph(MarkerColorOpt) -outline
200    set graph(ElementShowOption) "-hide 0"
201    set graph(ElementHideOption) "-hide 1"
202} else {
203    set graph(MarkerColorOpt) -color
204    set graph(ElementShowOption) "-mapped 1"
205    set graph(ElementHideOption) "-mapped 0"
206}
207
208# called by a trace on expgui(lblfontsize)
209proc setfontsize {a b c} {
210    global expgui graph
211    catch {
212        font config lblfont -size [expr -$expgui(lblfontsize)]
213        # this forces a redraw of the plot by changing the title to itself
214        .g configure -title [.g cget -title]
215    }
216}
217# define a font used for labels
218if {$tcl_version >= 8.0} {
219    font create lblfont -family Helvetica -size [expr -$expgui(lblfontsize)]
220    trace variable expgui(lblfontsize) w setfontsize
221}
222
223proc readdata {box} {
224    global expgui modtime expnam
225    if [catch {
226        set modtime [file mtime $expnam.EXP]
227        set loadtime [time {
228            if {$expgui(tcldump) == ""} {
229                set p HSTDMP
230                readdata_hst $box
231            } else {
232                set p TCLDUMP
233                readdata_tcl $box
234            }
235        }]
236        if $expgui(debug) {
237            tk_dialog .time "Timing info" \
238                    "Histogram loading took $loadtime" "" 0 OK
239        }
240    } errmsg] {
241        if $expgui(debug) {
242            catch {console show}
243            error $errmsg
244        }
245        $box config -title "Read error"
246        MyMessageBox -parent . -title "$p Error" \
247                -message "There was an error running the $p program. The most common reason for this is that POWPREF & GENLES have not been run.\n\nError message: $errmsg" \
248                -icon error -type Continue -default continue \
249                -helplink "expguierr.html TCLDUMPError"
250        update
251    }
252    $box element show [lsort -decreasing [$box element show]]
253    global program
254    if {$program == "bkgedit"}  bkghstInit
255}
256   
257proc readdata_hst {box} {
258    global expgui expnam reflns
259    global lasthst
260    global hst peakinfo xunits
261    $box config -title "(Histogram update in progress)"
262    update
263    # parse the output of a file
264    set lasthst $hst
265###########################################################################
266#       set input [open histdump.inp w]
267#       puts $input "$hst"
268#       close $input
269#       set input [open "| $expgui(gsasexe)/hstdump $expnam  < histdump.inp" w+]
270###########################################################################
271    # use histdmp for histogram info
272    set input [open histdump$hst.inp w]
273    puts $input "$expnam"
274    puts $input "L"
275    puts $input "$hst"
276    puts $input "0"
277    close $input
278    # use hstdmp without an experiment name so that output
279    # is not sent to the .LST file
280    set input [open "| $expgui(gsasexe)/hstdmp < histdump$hst.inp" r]
281   
282    # initalize arrays
283    set num -1
284    set xlist {}
285    set obslist {}
286    set calclist {}
287    set bcklist {}
288    set xunits {}
289    # define a list of reflection positions for each phase
290    for {set i 1} {$i < 10} {incr i} {
291        set reflns($i) {}
292    }
293    set i 0
294    while {[gets $input line] >= 0} {
295        incr i
296        # run update every 50th line
297        if {$i > 50} {set i 0; update}
298        if [scan $line %d num] {
299            if {$num > 0} {
300                set Ispec 0
301                set X -999
302                scan [string range $line 8 end] %e%e%e%e%e%e \
303                        X Iobs Icalc Ispec fixB fitB
304                #puts $line
305                # eliminate excluded points
306                if {$Ispec > 0.0 && $X >= 0} {
307                    lappend xlist $X
308                    lappend obslist $Iobs
309                    lappend calclist $Icalc
310                    lappend bcklist [expr {$fixB + $fitB}]
311                }
312                # add peaks to peak lists
313                #    puts "[string range $line 6 6]"
314                # is this 6 or 7; 6 on win & 7 on SGI
315                if [regexp {[1-9]} [string range $line 6 7] ph] {
316                    lappend reflns($ph) $X
317                }
318            }
319        } else {
320            regexp {Time|Theta|keV} $line xunits
321        }
322    }
323    if {$xunits == "Theta"} {set xunits "2-Theta"}
324    close $input
325    catch {file delete histdump$hst.inp}
326    xvec set $xlist
327    obsvec set $obslist
328    calcvec set $calclist
329    bckvec set $bcklist
330    diffvec set [obsvec - calcvec]
331    global obsvec calcvec diffvec
332    set maxdiff  [set diffvec(max)]
333    set cmin [set calcvec(min)]
334    set omin [set obsvec(min)]
335    set cmax [set calcvec(max)]
336    set omax [set obsvec(max)]
337    set expgui(min) [expr {$omin < $cmin ? $omin : $cmin}]
338    set expgui(max) [expr {$omax > $cmax ? $omax : $cmax}]
339    set ymin1 [expr {$cmin - 1.1*$maxdiff}]
340    set ymin2 [expr {$omin - 1.1*$maxdiff}]
341    if {$ymin1 < $ymin2} {
342        diffvec set [diffvec + $ymin1]
343    } {
344        diffvec set [diffvec + $ymin2]
345    }
346    plotdata
347}
348
349proc readdata_tcl {box} {
350    global expgui expnam reflns
351    global lasthst graph
352    global hst peakinfo xunits yunits
353    $box config -title "(Histogram update in progress)"
354    update
355    # parse the output of a file
356    set lasthst $hst
357    # use tcldump
358    set input [open histdump$hst.inp w]
359    puts $input "$hst"
360    # x units -- native
361    puts $input "$graph(xunits)"
362    # y units  -- native
363    puts $input "$graph(yunits)"
364    # format (if implemented someday)
365    puts $input "0"
366    close $input
367    # initalize arrays
368    set X {}
369    set OBS {}
370    set CALC {}
371    set BKG {}
372    set WGT {}
373    global refhkllist refphaselist refpos
374    set refpos {}
375    set refhkllist {}
376    set refphaselist {}
377    for {set i 1} {$i < 10} {incr i} {
378        set reflns($i) {}
379    }
380    eval [exec $expgui(tcldump) $expnam < histdump$hst.inp]
381    catch {file delete histdump$hst.inp}
382    if {$X == ""} {
383        $box config -title "(Error reading Histogram $hst)"
384        foreach elem [$box element show] {
385           eval $box element config $elem $graph(ElementHideOption)
386        }
387        return
388    }
389    foreach elem [$box element names] {
390        eval $box element config $elem $graph(ElementShowOption)
391    }
392    xvec set $X
393    obsvec set $OBS
394    calcvec set $CALC
395    bckvec set $BKG
396    refposvec set $refpos
397    diffvec set [obsvec - calcvec]
398    if {$graph(chi2)} {
399        wifdvec set $WGT
400        wifdvec set [wifdvec * diffvec]
401        wifdvec set [wifdvec * diffvec]
402        # now do a running sum
403        set sum 0
404        set sumlist {}
405        foreach n [wifdvec range 0 end] {
406            set sum [expr {$sum + $n}]
407            lappend sumlist $sum
408        }
409        wifdvec set $sumlist
410        wifdvec set [wifdvec / [wifdvec length]]
411    }
412    if $graph(backsub) {
413        obsvec set [obsvec - bckvec]
414        calcvec set [calcvec - bckvec]
415    }
416    global obsvec calcvec diffvec
417    set maxdiff  [set diffvec(max)]
418    set cmin [set calcvec(min)]
419    set omin [set obsvec(min)]
420    set cmax [set calcvec(max)]
421    set omax [set obsvec(max)]
422    set expgui(min) [expr {$omin < $cmin ? $omin : $cmin}]
423    set expgui(max) [expr {$omax > $cmax ? $omax : $cmax}]
424    set ymin1 [expr {$cmin - 1.1*$maxdiff}]
425    set ymin2 [expr {$omin - 1.1*$maxdiff}]
426    if {$ymin1 < $ymin2} {
427        diffvec set [diffvec + $ymin1]
428    } {
429        diffvec set [diffvec + $ymin2]
430    }
431   
432    plotdata
433}
434
435proc lblhkl {plot x} {
436    global blt_version expgui tcl_platform tcl_version
437    global refhkllist refphaselist peakinfo refpos
438    # look for peaks within pixelregion pixels or the entire plot range
439    if {$x == "all"} {
440        foreach {xmin xmax} [$plot xaxis limits] {}
441    } else {
442        set xmin [$plot xaxis invtransform [expr {$x - $expgui(pixelregion)}]]
443        set xmax [$plot xaxis invtransform [expr {$x + $expgui(pixelregion)}]]
444    }
445    set peaknums [refposvec search $xmin $xmax]
446    set peaklist {}
447    # create a box, if needed
448    if {$expgui(hklbox)} {
449        catch {
450            toplevel .hkl
451            text .hkl.txt -width 30 -height 10 -wrap none \
452                    -yscrollcommand ".hkl.yscroll set"
453            scrollbar .hkl.yscroll -command ".hkl.txt yview"
454            grid .hkl.txt -column 0 -row 1 -sticky nsew
455            grid .hkl.yscroll -column 1 -row 1 -sticky ns
456            grid columnconfigure .hkl 0 -weight 1
457            grid rowconfigure .hkl 1 -weight 1
458            wm title .hkl "Liveplot HKL Labels"
459            wm iconname .hkl HKL
460            .hkl.txt insert end "Phase\thkl\tPosition"
461        }
462    }
463    set xcen 0
464    set lbls 0
465    foreach peak $peaknums {
466        # put all hkls, all phases in the box
467        if {$expgui(hklbox)} {
468            catch {
469                .hkl.txt insert end "\n[lindex $refphaselist $peak]"
470                .hkl.txt insert end "\t[lindex $refhkllist $peak]"
471                .hkl.txt insert end "\t[lindex $refpos $peak]"
472                .hkl.txt see end
473            }
474        }
475        # label phases with tick marks
476        if [set peakinfo(flag[lindex $refphaselist $peak])] {
477            set pos [refposvec range $peak $peak]
478            if {$lbls <= 0} {
479                set xcen $pos
480                set peaklist [lindex $refhkllist $peak]
481                set lbls 1
482            } elseif {abs($xcen/$lbls-$pos) <= $expgui(pixelregion)} {
483                set xcen [expr {$xcen + $pos}]
484                lappend peaklist [lindex $refhkllist $peak]
485                incr lbls
486            } else {
487                puthkllbl $plot $peaklist $xcen $lbls
488                set xcen $pos
489                set peaklist [lindex $refhkllist $peak]
490                set lbls 1
491            }
492        }
493    }
494    puthkllbl $plot $peaklist $xcen $lbls
495}
496
497proc puthkllbl {plot peaklist xcen lbls} {
498    global blt_version tcl_platform tcl_version expgui
499    if {$peaklist == ""} return
500    set xcen [expr {$xcen / $lbls}]
501    # avoid bug in BLT 2.3 where Inf does not work for text markers
502    if {$blt_version == 2.3} {
503        set ycen [lindex [$plot yaxis limits] 1]
504    } else  {
505        set ycen Inf
506    }
507    # older BLT versions can't rotate text in windows
508    if {$tcl_platform(platform) == "windows" && \
509            ($blt_version <= 2.3 || $blt_version == 8.0)} {
510        regsub -all { } $peaklist "\n" peaklist
511        set mark [$plot marker create text -coords "$xcen $ycen" \
512                -text $peaklist -anchor n -bg "" -name hkl$xcen]
513    } else {
514        set mark [$plot marker create text -coords "$xcen $ycen" \
515                -rotate 90 -text $peaklist -anchor n -bg "" -name hkl$xcen]
516    }
517    if {$tcl_version >= 8.0} {
518        $plot marker config hkl$xcen -font lblfont
519    }
520    if {$expgui(fadetime) > 0} {
521        catch {
522            after [expr {$expgui(fadetime) * 1000 }] \
523                    "catch \{ $plot marker delete $mark \}"
524        }
525    }
526}
527
528proc delallhkllbl {plot} {
529    catch {
530        eval $plot marker delete [$plot marker names hkl*]
531    }
532}
533
534proc plotdata {} {
535    global expnam hst peakinfo xunits yunits cycle reflns modtime
536    global lasthst graph expgui box
537
538    # is there a new histogram to load?
539    if {$hst != $lasthst} {
540        xvec set {}
541        xvec notify now
542        set cycle -1
543        set modtime 0
544        $box config -title "Please wait: loading histogram $hst"
545        update
546        return
547    }
548    $box config -title "$expnam cycle $cycle Hist $hst"
549    $box xaxis config -title $xunits
550    $box yaxis config -title $yunits
551    setlegend $box $graph(legend)
552    # reconfigure the data
553    $box element configure 3 \
554            -symbol $peakinfo(obssym) -color $graph(color_obs) \
555            -pixels [expr 0.125 * $peakinfo(obssize)]i
556    $box element config 0 -color $graph(color_chi2)
557    $box element config 1 -color $graph(color_bkg)
558    $box element config 2 -color $graph(color_calc)
559    $box element config 4 -color $graph(color_diff)
560    global program
561    if {$program == "bkgedit"}  {
562        $box element config 12 -color $graph(color_input) \
563                -pixels [expr 0.125 * $peakinfo(inpsize)]i \
564                -symbol $peakinfo(inpsym)
565        $box element config 11 -color $graph(color_fit)
566    }
567    xvec notify now
568    obsvec notify now
569    calcvec notify now
570    bckvec notify now
571    diffvec notify now
572    wifdvec notify now
573    # now deal with peaks
574    for {set i 1} {$i < 10} {incr i} {
575        if {$expgui(autotick)} {
576            set div [expr {( $expgui(max) - $expgui(min) )/40.}]
577            set ymin [expr {$expgui(min) - ($i+1) * $div}]
578            set ymax [expr {$expgui(min) - $i * $div}]
579        } else {
580            set ymin $peakinfo(min$i)
581            set ymax $peakinfo(max$i)
582        }
583        set j 0
584        if [set peakinfo(flag$i)] {
585            foreach X $reflns($i) {
586                incr j
587                catch {
588                    $box marker create line -name peaks${i}_$j
589                }
590                $box marker config peaks${i}_$j  -under 1 \
591                        -coords "$X $ymin $X $ymax"
592                catch {
593                    $box marker config peaks${i}_$j \
594                            $graph(MarkerColorOpt) [list $peakinfo(color$i)]
595                    if $peakinfo(dashes$i) {
596                        $box marker config peaks${i}_$j -dashes "5 5"
597                    }
598                }
599            }
600            catch {$box element create phase$i}
601            catch {
602                $box element config phase$i -color $peakinfo(color$i) \
603                        -label $graph(label$i)
604            }
605        } else {
606            eval $box marker delete [$box marker names peaks${i}_*]
607            eval $box element delete [$box element names phase$i]
608        }
609    }
610    # force an update of the plot as BLT may not
611    $box config -title [$box cget -title]
612    update
613}
614
615proc setlegend {box legend} {
616    global blt_version
617    if {$blt_version >= 2.3 && $blt_version < 8.0} {
618        if $legend {
619            $box legend config -hide no
620        } else {
621            $box legend config -hide yes
622        }
623    } else {
624        if $legend {
625            $box legend config -mapped yes
626        } else {
627            $box legend config -mapped no
628        }
629    }
630}
631
632proc minioptionsbox {num} {
633    global blt_version tcl_platform peakinfo expgui
634    set bx .opt$num
635    catch {destroy $bx}
636    toplevel $bx
637    wm iconname $bx "Phase $num options"
638    wm title $bx "Phase $num options"
639
640    set i $num
641    pack [label $bx.0 -text "Phase $i reflns" ] -side top
642    pack [checkbutton $bx.1 -text "Show reflections" \
643            -variable peakinfo(flag$i)] -side top
644    # remove option that does not work
645    if {$blt_version != 8.0 || $tcl_platform(platform) != "windows"} {
646        pack [checkbutton $bx.2 -text "Use dashed line" \
647                -variable peakinfo(dashes$i)] -side top
648    }
649    if !$expgui(autotick) {
650        pack [frame $bx.p$i -bd 2 -relief groove] -side top
651        #       pack [checkbutton $bx.p$i.0 -text "Show phase $i reflns" \
652                #               -variable peakinfo(flag$i)] -side left -anchor w
653        pack [label $bx.p$i.1 -text "  Y min:"] -side left
654        pack [entry $bx.p$i.2 -textvariable peakinfo(min$i) -width 5] \
655                -side left
656        pack [label $bx.p$i.3 -text "  Y max:"] -side left
657        pack [entry $bx.p$i.4 -textvariable peakinfo(max$i) -width 5] \
658                -side left
659    }
660    pack [frame $bx.c$i -bd 2 -relief groove] -side top
661   
662    pack [label $bx.c$i.5 -text " color:"] -side left
663    pack [entry $bx.c$i.6 -textvariable peakinfo(color$i) -width 12] \
664            -side left
665    pack [button $bx.c$i.2 -bg $peakinfo(color$i) -state disabled] -side left
666    pack [button $bx.c$i.1 -text "Color\nmenu" \
667            -command "setcolor $i"] -side left
668
669    pack [frame $bx.l$i -bd 2 -relief groove] -side top
670   
671    pack [label $bx.l$i.1 -text " Phase label:"] -side left
672   
673    pack [entry $bx.l$i.2 -textvariable graph(label$i) -width 20] \
674            -side left
675
676    pack [frame $bx.b] -side top
677    pack [button $bx.b.4 -command "destroy $bx; plotdata" \
678            -text Close ] -side right
679}
680
681proc setcolor {num} {
682    global peakinfo
683    set color [tk_chooseColor -initialcolor $peakinfo(color$num) -title "Choose color"]
684    if {$color == ""} return
685    set peakinfo(color$num) $color
686}
687
688proc makepostscriptout {} {
689    global graph box
690    if !$graph(printout) {
691        set out [open "| $graph(outcmd) >& liveplot.msg" w]
692        catch {
693            puts $out [$box postscript output -landscape 1 \
694                -decorations no -height 7.i -width 9.5i]
695            close $out
696        } msg
697        catch {
698            set out [open liveplot.msg r]
699            if {$msg != ""} {append msg "\n"}
700            append msg [read $out]
701            close $out
702            catch {file delete liveplot.msg}
703        }
704        if {$msg != ""} {
705            tk_dialog .msg "file created" \
706                    "Postscript file processed with command \
707                    $graph(outcmd). Result: $msg" "" 0 OK
708        } else {
709            tk_dialog .msg "file created" \
710                    "Postscript file processed with command \
711                    $graph(outcmd)" "" 0 OK
712        }
713    } else {
714        $box postscript output $graph(outname) -landscape 1 \
715                -decorations no -height 7.i -width 9.5i   
716        tk_dialog .msg "file created" \
717                "Postscript file $graph(outname) created" "" 0 OK
718    }
719}
720
721proc setprintopt {page} {
722    global graph
723    if $graph(printout) {
724        $page.4.1 config -fg black
725        $page.4.2 config -fg black -state normal
726        $page.6.1 config -fg #888
727        $page.6.2 config -fg #888 -state disabled
728    } else {
729        $page.4.1 config -fg #888
730        $page.4.2 config -fg #888 -state disabled
731        $page.6.1 config -fg black
732        $page.6.2 config -fg black -state normal
733    }
734}
735
736proc setpostscriptout {} {
737    global graph tcl_platform
738    set box .out
739    catch {destroy $box}
740    toplevel $box
741    focus $box
742    wm title $box "Set PS options"
743    pack [frame $box.4] -side top -anchor w -fill x
744    pack [checkbutton $box.4.a -text "Write PostScript files" \
745            -variable graph(printout) -offvalue 0 -onvalue 1 \
746            -command "setprintopt $box"] -side left -anchor w
747    pack [entry $box.4.2 -textvariable graph(outname)] -side right -anchor w
748    pack [label $box.4.1 -text "PostScript file name:"] -side right -anchor w
749    pack [frame $box.6] -side top -anchor w -fill x
750    pack [checkbutton $box.6.a -text "Print PostScript files" \
751            -variable graph(printout) -offvalue 1 -onvalue 0 \
752            -command "setprintopt $box" ] -side left -anchor w
753    pack [entry $box.6.2 -textvariable graph(outcmd)] -side right -anchor w
754    pack [label $box.6.1 -text "Command to print files:"] -side right -anchor w
755
756    pack [button $box.a -text "Close" -command "destroy $box"] -side top
757    if {$tcl_platform(platform) == "windows"} {
758        set graph(printout) 1
759        $box.4.a config -state disabled
760        $box.6.a config -fg #888 -state disabled
761    }
762    setprintopt $box
763}
764
765#-------------------------------------------------------------------------
766# export current plot to Grace
767#-------------------------------------------------------------------------
768if {$tcl_platform(platform) == "unix"} {
769    set graph(GraceFile) /tmp/grace_out.agr
770} else {
771    set graph(GraceFile) C:/graceout.agr
772}
773proc exportgrace {} {
774    global graph box
775    global tcl_platform graph
776    catch {toplevel .export}
777    raise .export
778    eval destroy [grid slaves .export]
779    set col 5
780    grid [label .export.1a -text Title:] -column 1 -row 1
781    set graph(title) [$box cget -title]
782    grid [entry .export.1b -width 60 -textvariable graph(title)] \
783            -column 2 -row 1 -columnspan 4
784    grid [label .export.2a -text Subtitle:] -column 1 -row 2
785    grid [entry .export.2b -width 60 -textvariable graph(subtitle)] \
786            -column 2 -row 2 -columnspan 4
787    grid [label .export.3a -text "File name:"] -column 1 -row 3
788    grid [entry .export.3b -width 60 -textvariable graph(GraceFile)] \
789            -column 2 -row 3 -columnspan 4
790    grid [button .export.help -text Help -bg yellow \
791            -command "MakeWWWHelp liveplot.html grace"] \
792            -column [incr col -1] -row 4
793    grid [button .export.c -text "Close" \
794            -command "set graph(export) 0; destroy .export"] \
795            -column [incr col -1] -row 4
796    if {$tcl_platform(platform) == "unix" && [auto_execok xmgrace] != ""} {
797        grid [button .export.d -text "Export & \nstart grace" \
798            -command "set graph(export) 1; destroy .export"] \
799                -column [incr col -1] -row 4
800    }
801    grid [button .export.e -text "Export" \
802            -command "set graph(export) 2; destroy .export"] \
803            -column [incr col -1] -row 4
804    tkwait window .export
805    if {$graph(export) == 0} return
806    if {[catch {
807        set fp [open $graph(GraceFile) w]
808        puts $fp [output_grace $box $graph(title) $graph(subtitle)]
809        close $fp
810    } errmsg]} {
811        MyMessageBox -parent . -title "Export Error" \
812                -message "An error occured during the export: $errmsg" \
813                -icon error -type Ignore -default ignore
814        return
815    }
816
817    if {$graph(export) == 1} {
818        set err [catch {exec xmgrace $graph(GraceFile) &} errmsg]
819        if $err {
820        MyMessageBox -parent . -title "Grace Error" \
821                -message "An error occured launching grace (xmgrace): $errmsg" \
822                -icon error -type Ignore -default ignore
823        }
824    } else {
825        MyMessageBox -parent . -title "OK" \
826                -message "File $graph(GraceFile) created" \
827                -type OK -default ok
828    }
829}
830
831proc setlblopts {} {
832    global expgui tcl_platform tcl_version
833    set box .out
834    catch {destroy $box}
835    toplevel $box
836    focus $box
837    wm title $box "Set hkl options"
838    pack [frame $box.c] -side top  -anchor w
839    pack [label $box.c.l -text "HKL label\nerase time:"] -side left
840    pack [entry $box.c.e -textvariable expgui(fadetime) -width 8] \
841            -side left
842    pack [label $box.c.l1 -text seconds] -side left
843    pack [frame $box.d] -side top  -anchor w
844    pack [label $box.d.l -text "HKL label size:"] -side left
845    pack [entry $box.d.e -textvariable expgui(lblfontsize) -width 4] \
846            -side left
847    pack [label $box.d.l1 -text pixels] -side left
848    # old versions if tcl/tk don't support the font command
849    if {$tcl_version < 8.0} {
850        $box.d.l config -fg #888
851        $box.d.e config -fg #888 -state disabled
852        $box.d.l1 config -fg #888
853    }
854    pack [frame $box.f] -side top  -anchor w
855    pack [label $box.f.l -text "HKL search region:"] -side left
856    pack [entry $box.f.e -textvariable expgui(pixelregion) -width 3] \
857            -side left
858    pack [label $box.f.l1 -text pixels] -side left
859    pack [frame $box.e] -side top  -anchor w
860    pack [checkbutton $box.e.b -text "Separate window for HKL labels"\
861            -variable expgui(hklbox)] -side left
862    pack [button $box.a -text "Close" -command "destroy $box"] -side top
863}
864
865proc getsymopts {"sym obs"} {
866    global expgui peakinfo
867    set box .out
868    catch {destroy $box}
869    toplevel $box
870    focus $box
871    wm title .out "set $sym symbol"
872    pack [frame $box.d] -side left -anchor n
873    pack [label $box.d.t -text "Symbol type"] -side top
874    set expgui(sym) $peakinfo(${sym}sym)
875    set expgui(size) $peakinfo(${sym}size)
876    foreach symbol {square circle diamond triangle plus cross \
877            splus scross} \
878            symbol_name {square circle diamond triangle plus cross \
879            thin-plus thin-cross} {
880        pack [radiobutton $box.d.$symbol \
881                -text $symbol_name -variable expgui(sym) \
882                -value $symbol] -side top -anchor w
883    }
884    pack [frame $box.e] -side left -anchor n -fill y
885    pack [label $box.e.l -text "Symbol Size"] -side top
886    pack [scale $box.e.s -variable expgui(size) \
887            -from .1 -to 3 -resolution 0.05] -side top
888    pack [frame $box.a] -side bottom
889    pack [button $box.a.1 -text "Apply" -command "setsymopts $sym"] -side left
890    pack [button $box.a.2 -text "Close" -command "destroy $box"] -side left
891}
892proc setsymopts {sym} {
893    global peakinfo expgui
894    if {$peakinfo(${sym}sym) != $expgui(sym)} {set peakinfo(${sym}sym) $expgui(sym)}
895    if {$peakinfo(${sym}size) != $expgui(size)} {set peakinfo(${sym}size) $expgui(size)}
896}
897
898# save some of the global options in ~/.gsas_config
899proc SaveOptions {} {
900    global graph expgui peakinfo
901    set fp [open [file join ~ .gsas_config] a]
902    foreach v {printout legend outname outcmd autoraise chi2} {
903        puts $fp "set graph($v) $graph($v)"
904    }
905    foreach v {diff chi2 bkg calc obs input fit} {
906        puts $fp "set graph(color_$v) $graph(color_$v)"
907    }
908    foreach v {font lblfontsize fadetime hklbox pixelregion autotick} {
909        puts $fp "set expgui($v) $expgui($v)"
910    }
911    foreach v {obssym obssize inpsym inpsize} {
912        puts $fp "set peakinfo($v) $peakinfo($v)"
913    }
914    close $fp
915}
916
917proc aboutliveplot {} {
918    global Revision
919    tk_dialog .warn About "
920GSAS\n\
921A. C. Larson and\n R. B. Von Dreele,\n LANSCE, Los Alamos\n\n\
922LIVEPLOT\nB. Toby, NIST\nNot subject to copyright\n\n\
923$Revision\n\
924" {} 0 OK
925}
926
927proc getcycle {} {
928    global expnam
929    set cycle -1
930    catch {
931        set fp [open $expnam.EXP r]
932        set text [read $fp]
933        close $fp
934        regexp {GNLS  RUN.*Total cycles run *([0-9]*) } $text x cycle
935    }
936    return $cycle
937}
938
939proc updateifnew {} {
940    global cycle modtime expnam env tcl_platform graph
941    # has the .EXP file been changed?
942    set newmodtime $modtime
943    catch {set newmodtime [file mtime $expnam.EXP]}
944    if {$newmodtime != $modtime} {
945        # are we in windows and are "locked?" If not, OK to update
946        if {$tcl_platform(platform) == "windows" && [file exists expgui.lck]} {
947            .g config -title "(Experiment directory locked)"
948        } else {
949            set modtime [file mtime $expnam.EXP]
950            set newcycle [getcycle]
951            if {$newcycle != $cycle} {
952                set cycle $newcycle
953                readdata .g
954            }
955            if {$tcl_platform(platform) == "windows" && $graph(autoraise)} {
956                # raise does not seem to be global in Windows,
957                # but this works in Win-95
958                # nothing seems to work in Win-NT
959                wm withdraw .
960                wm deiconify .
961            } elseif {$graph(autoraise)} {
962                raise .
963            }
964        }
965    }
966    # check again in a second
967    after 1000 updateifnew
968}
969
970proc plotdataupdate {array element action} {
971    global box peakinfo reflns graph
972    # parse the element
973    regexp {([a-z]*)([0-9]*)} $element junk var num
974    if {$var == "color"} {
975        if {$peakinfo($element) == ""} return
976        if [catch {
977            .opt$num.c$num.2 config -bg $peakinfo($element)
978        } ] return
979        set i $num
980        set j 0
981        if [set peakinfo(flag$i)] {
982            catch {
983                $box element config phase$i -color $peakinfo(color$i)
984            }
985            foreach X $reflns($i) {
986                incr j
987                catch {
988                    $box marker config peaks${i}_$j \
989                            $graph(MarkerColorOpt) [list $peakinfo(color$i)]
990                }
991            }
992        }
993        return
994    }
995    waitmsg {Updating}
996    plotdata
997    donewaitmsg
998}
999proc ShowCumulativeChi2 {} {
1000    global graph box
1001    if $graph(chi2) {
1002        eval $box y2axis config $graph(ElementShowOption)
1003        eval $box element config 0 $graph(ElementShowOption) -label "Chi2"
1004        set cycle [getcycle]
1005        readdata .g
1006    } else {
1007        eval $box element config 0 $graph(ElementHideOption)
1008        eval $box y2axis config $graph(ElementHideOption)
1009        $box element config 0 -label ""
1010    }
1011}
1012# evaluate the Chebyshev polynomial with coefficients A at point x
1013# coordinates are rescaled from $xmin=-1 to $xmax=1
1014proc chebeval {A x xmin xmax} {
1015    set xs [expr {-1 + 2 * (1.*$x - $xmin) / (1.*$xmax - 1.*$xmin)}]
1016    set Tpp 0
1017    set Tp 0
1018    set total 0
1019    foreach a $A {
1020        if {$Tpp == $Tp && $Tp == 0} {
1021            set T 1
1022        } elseif {$Tpp == 0} {
1023            set T $xs
1024        } else {       
1025            set T [expr {2. * $xs * $Tp - $Tpp}]
1026        }
1027        set total [expr {$total + $a * $T}]
1028        set Tpp $Tp
1029        set Tp $T
1030    }
1031    return $total
1032}
1033
1034# change the binding of the mouse, based on the selected mode
1035proc bkgEditMode {b} {
1036    global zoomcommand box
1037    # get binding
1038    set bindtag $box
1039    catch {
1040        if {[bind bltZoomGraph] != ""} {
1041            set bindtag bltZoomGraph
1042        }
1043    }
1044    # save the zoom command
1045    if [catch {set zoomcommand}] {
1046        set zoomcommand [bind $bindtag <1>]
1047        .bkg.f.fit1 config -state disabled
1048        .bkg.f.terms config -state disabled
1049    }
1050    if {$b == ""} {
1051        foreach c {1 2 3} {
1052            if {[.bkg.l.b$c cget -relief] == "sunken"} {set b $c}
1053        }
1054    }
1055    foreach c {1 2 3} {
1056        if {$c == $b} {
1057            .bkg.l.b$c config -relief sunken
1058        } else {
1059            .bkg.l.b$c config -relief raised
1060        }
1061    }
1062    # reset previous mode; if in the middle
1063    if {[string trim [bind $box <Motion>]] != ""} {
1064        blt::ResetZoom $box
1065    }
1066    if {$b == 2} {
1067        bind $bindtag <1> "bkgAddPoint %x %y"
1068        .g config -cursor arrow
1069    } elseif {$b == 3} {
1070        bind $bindtag <1> "bkgDelPoint %x %y"
1071        .g config -cursor circle
1072    } else {
1073        bind $bindtag <1> $zoomcommand
1074        .g config -cursor crosshair
1075    }
1076}
1077
1078# plot the background points
1079proc bkgPointPlot {} {
1080    global bkglist termmenu expgui expnam hst tmin tmax
1081    set l {}
1082    set fp [open $expnam.bkg$hst w]
1083    puts $fp "y p h e $hst b ! fixed background points for use in BKGEDIT"
1084    foreach p $bkglist {
1085        puts $fp "i\t$p\t0.0"
1086        append l " $p"
1087    }
1088    if {[llength $bkglist] > 0} {
1089        puts $fp "i\t[expr $tmin*0.99] [lindex [lindex $bkglist 0] 1]\t0.0"
1090        puts $fp "i\t[expr $tmax*1.01] [lindex [lindex $bkglist end] 1]\t0.0"
1091    }
1092    close $fp
1093    .g element config 12 -data $l
1094    if {[set l [llength $bkglist]] > 3} {
1095        .bkg.f.fit1 config -state normal
1096        .bkg.f.terms config -state normal
1097        $termmenu delete 0 end
1098        set imax {}
1099        for {set i 2} {$i <= $l/1.5} {incr i 2} {
1100            $termmenu insert end radiobutton -label $i \
1101                    -variable expgui(FitOrder) -command "BkgFillTermBoxes nosave"
1102            set imax $i
1103        }
1104        if {$imax < $expgui(FitOrder)} {set expgui(FitOrder) $imax}
1105    } else {
1106        .bkg.f.fit1 config -state disabled
1107        .bkg.f.terms config -state disabled
1108        set expgui(FitOrder) 2
1109    }
1110}
1111
1112# add a bkg point at screen coordinates x,y
1113proc bkgAddPoint {x y} {
1114    global bkglist tmin tmax
1115    set xy [.g invtransform $x $y]
1116    set x [lindex $xy 0]
1117    if {$x < $tmin} {set x $tmin}
1118    if {$x > $tmax} {set x $tmax}
1119    lappend bkglist [list $x [lindex $xy 1]]
1120    set bkglist [lsort -real -index 0  $bkglist]
1121    bkgFillPoints
1122    bkgPointPlot
1123}
1124
1125# delete the bkg point closest to screen coordinates x,y
1126proc bkgDelPoint {x y} {
1127    global bkglist
1128    set closest {}
1129    set dist2 {}
1130    set i -1
1131    foreach p $bkglist {
1132        incr i
1133        set sxy [eval .g transform $p]
1134        if {$closest == ""} {
1135            set closest $i
1136            set dist2 0
1137            foreach v1 $sxy v2 "$x $y" {
1138                set dist2 [expr {$dist2 + ($v1 - $v2)*($v1 - $v2)}]
1139            }
1140        } else {
1141            set d2 0
1142            foreach v1 $sxy v2 "$x $y" {
1143                set d2 [expr {$d2 + ($v1 - $v2)*($v1 - $v2)}]
1144            }
1145            if {$d2 < $dist2} {
1146                set closest $i
1147                set dist2 $d2
1148            }           
1149        }
1150    }
1151    set bkglist [lreplace $bkglist $closest $closest]
1152    bkgPointPlot
1153    bkgFillPoints
1154}
1155
1156# initialize the background plot
1157proc bkghstInit {} {
1158    global bkglist tmin tmax hst expnam termlist expgui
1159    set tmin [histinfo $hst tmin]
1160    set tmax [histinfo $hst tmax]
1161    if {[catch {expr $tmin}] || [catch {expr $tmax}]} {
1162        tk_dialog .err "MIN/MAX Error" "Error -- Unable read tmin or tmax (has POWPREF been run?" \
1163                error 0 Quit
1164        destroy .
1165    }
1166
1167    set bkglist {}
1168    if [file exists $expnam.bkg$hst] {
1169        catch {
1170            set fp [open $expnam.bkg$hst r]
1171            gets $fp line
1172            while {[gets $fp line]>=0} {
1173                set x [lindex $line 1]
1174                set y [lindex $line 2]
1175                if {$x >= $tmin && $x <= $tmax} {
1176                    lappend bkglist [list $x $y]
1177                }
1178            }
1179        }
1180        close $fp
1181    }
1182
1183    bkgEditMode 1
1184    bkgPointPlot
1185    bkgFillPoints
1186    set termlist ""
1187    set expgui(FitOrder) 2
1188    BkgFillTermBoxes nosave
1189}
1190
1191proc bkgFit {button} {
1192    global bkglist termlist expgui
1193    # keep the button down while working
1194    $button config -relief sunken
1195    update
1196    # make a list of X & Y values
1197    foreach p $bkglist {
1198        lappend S 1.
1199        foreach v $p var {X Y} {
1200            lappend $var $v
1201        }
1202    }
1203
1204    # perform the Fit
1205    set termlist [FitBkgFunc $X $Y $expgui(FitOrder) $expgui(FitFunction) \
1206            $expgui(RadiiList)]
1207    # set the bkg terms in the edit boxes & update the plot
1208    BkgFillTermBoxes
1209    $button config -relief raised
1210}
1211
1212# put the Background coefficients into edit widgets
1213proc BkgFillTermBoxes {"save {}"} {
1214    global termlist expgui
1215    global bkgeditbox
1216    catch {destroy .bkg.canvas.fr}
1217    set top [frame .bkg.canvas.fr]
1218    .bkg.canvas create window 0 0 -anchor nw -window $top
1219    # delete trace on bkgeditbox
1220    foreach v [ trace vinfo bkgeditbox] {
1221        eval trace vdelete bkgeditbox $v
1222    }
1223
1224    .bkg.cw config -state normal
1225    set k 0
1226    if {$expgui(FitFunction) == 3} {
1227        # o is number of refinable terms
1228        set o [expr {2 + ($expgui(FitOrder) - 2)/2}]
1229        grid [label $top.lbl -text terms] -col $k -row 1
1230        if {$expgui(FitOrder) >= 4} {
1231            grid [label $top.rlbl -text radii] -col $k -row 2
1232        }
1233        incr k
1234        set width 7
1235    } else {
1236        set o $expgui(FitOrder)
1237        set width 10
1238    }
1239    for {set i 0} {$i < $o} {incr i} {
1240        if {$i >= [llength $termlist]} {lappend termlist 0.}
1241        set bkgeditbox($i) [lindex $termlist $i]
1242        grid [frame $top.$i -relief groove -bd 3] -col $k -row 1
1243        grid [label $top.$i.l -text "[expr 1+$i]"] -col 1 -row 1
1244        grid [entry $top.$i.e -textvariable bkgeditbox($i) -width $width] \
1245                -col 2 -row 1
1246        if {$expgui(FitFunction) == 3 && $i > 1} {
1247            set j [expr $i-2]
1248            if {$j >= [llength $expgui(RadiiList)]} {lappend expgui(RadiiList) 0.}
1249            set bkgeditbox(r$j) [lindex $expgui(RadiiList) $j]
1250            if {$bkgeditbox(r$j) == 0} {
1251                set bkgeditbox(r$j) ??
1252            }
1253            grid [frame $top.r$j -relief groove -bd 3] \
1254                    -col [expr $k-2] -row 2
1255            grid [label $top.r$j.l -text "[expr -1+$i]"] -col 1 -row 1
1256            grid [entry $top.r$j.e -textvariable bkgeditbox(r$j) -width $width] \
1257                    -col 2 -row 1       
1258        }
1259        incr k
1260    }
1261    trace variable bkgeditbox w "BkgRecalcPlot $top"
1262    BkgRecalcPlot $top x x x
1263    update idletasks
1264    set sizes [grid bbox $top]
1265    .bkg.canvas config -scrollregion $sizes -height [lindex $sizes 3]
1266    # inhibit the save button, if requested
1267    if {$save == "nosave"} {
1268        .bkg.cw config -state disabled
1269        .g element configure 11 -xdata {} -ydata {}
1270        update
1271    }
1272}
1273
1274# respond to edits made to background terms
1275proc BkgRecalcPlot {top var i mode} {
1276    global bkgeditbox termlist expgui expgui(FitOrder)
1277
1278    set good 1
1279
1280    if {$expgui(FitFunction) == 3} {
1281        set expgui(RadiiList) {}
1282        for {set j 0} {$j < ($expgui(FitOrder) - 2)/2} {incr j} {
1283            lappend expgui(RadiiList) $bkgeditbox(r$j)
1284            if {[catch {expr $bkgeditbox(r$j)}]} {
1285                $top.r$j.e config -fg red
1286                set good 0
1287            } elseif {$bkgeditbox(r$j) == 0} {
1288                $top.r$j.e config -fg red
1289                set good 0
1290            } else {
1291                $top.r$j.e config -fg black
1292            }
1293        }
1294        set o [expr {2 + ($expgui(FitOrder) - 2)/2}]
1295    } else {
1296        set o $expgui(FitOrder)
1297    }
1298    set termlist {}
1299    for {set j 0} {$j < $o} {incr j} {
1300        lappend termlist $bkgeditbox($j)
1301        if {[catch {expr $bkgeditbox($j)}]} {
1302            $top.$j.e config -fg red
1303            set good 0
1304        } else {
1305            $top.$j.e config -fg black
1306        }
1307    }
1308
1309    # disable fit for invalid values
1310    if {$good} {
1311        .bkg.cw config -state normal
1312        .bkg.f.fit1 config -state normal
1313        # plot it
1314        set calcb [BkgEval $termlist $expgui(FitFunction) \
1315                [xvec range 0 end] $expgui(RadiiList)]
1316        .g element configure 11 -xdata xvec -ydata $calcb
1317        update
1318    } else {
1319        .bkg.cw config -state disabled
1320        .bkg.f.fit1 config -state disabled
1321        .g element configure 11 -xdata {} -ydata {}
1322        update
1323    }
1324}
1325
1326# put the bkg points into edit widgets
1327proc bkgFillPoints {} {
1328    global bkglist tmin tmax bkgedit
1329    # delete trace on bkgedit
1330    foreach v [ trace vinfo bkgedit] {
1331        eval trace vdelete bkgedit $v
1332    }
1333    catch {destroy .bkg.bc.fr}
1334    set top [frame .bkg.bc.fr]
1335    .bkg.bc create window 0 0 -anchor nw -window $top
1336    if {[llength $bkglist] == 0} {
1337        grid [label $top.0 -text "(no points defined)"] -col 1 -row 1
1338    } else {
1339        set i -1
1340        foreach p $bkglist {
1341            incr i
1342            grid [frame $top.$i -relief groove -bd 3] -col $i -row 1
1343            grid [label $top.$i.l -text "[expr 1+$i]"] -col 1 -rowspan 2 -row 1
1344            grid [entry $top.$i.ex -textvariable bkgedit(x$i) -width 13] \
1345                    -col 2 -row 1
1346            grid [entry $top.$i.ey -textvariable bkgedit(y$i) -width 13] \
1347                    -col 2 -row 2
1348            foreach val $p var {x y} {
1349                set bkgedit(${var}$i) $val
1350            }
1351        }
1352        trace variable bkgedit w "BkgRecalcBkg $top"
1353    }
1354    update idletasks
1355    set sizes [grid bbox $top]
1356    .bkg.bc config -scrollregion $sizes -height [lindex $sizes 3]
1357}
1358
1359# respond to edits made to bkg points
1360proc BkgRecalcBkg {top var i mode} {
1361    global bkgedit bkglist tmin tmax
1362    regexp {(.)([0-9]*)} $i junk var num
1363    if [catch {expr {$bkgedit($i)}}] {
1364        $top.$num.e$var config -fg red
1365    } else {
1366        $top.$num.e$var config -fg black
1367        set p [lindex $bkglist $num]
1368        if {$var == "x"} {
1369            set x $bkgedit($i)
1370            if {$x < $tmin} {set x $tmin}
1371            if {$x > $tmax} {set x $tmax}
1372            set bkglist [lreplace $bkglist $num $num \
1373                    [list $x [lindex $p 1]]]
1374        } else {
1375            set bkglist [lreplace $bkglist $num $num \
1376                    [list [lindex $p 0] $bkgedit($i)]]
1377        }
1378    }
1379        bkgPointPlot
1380}
1381
1382# convert x values to Q
1383proc toQ {xlist hst} {
1384    global expmap
1385    if {[string range $expmap(htype_$hst) 2 2] == "T"} {
1386        return [toftoQ $xlist $hst]
1387    } elseif {[string range $expmap(htype_$hst) 2 2] == "C"} {
1388        return [tttoQ $xlist $hst]
1389    } elseif {[string range $expmap(htype_$hst) 2 2] == "E"} {
1390        return [engtoQ $xlist $hst]
1391    } else {
1392        return {}
1393    }
1394}
1395# convert tof to Q
1396proc toftoQ {toflist hst} {
1397    set difc [expr {[histinfo $hst difc]/1000.}]
1398    set difc2 [expr {$difc*$difc}]
1399    set difa [expr {[histinfo $hst difa]/1000.}]
1400    set zero [expr {[histinfo $hst zero]/1000.}]
1401    set 2pi [expr {4.*acos(0.)}]
1402    set ans {}
1403    foreach tof $toflist {
1404        if {$tof == 0.} {
1405            lappend ans 99999.
1406        } elseif {$tof == 1000.} {
1407            lappend ans 0.
1408        } else {
1409            set td [expr {$tof-$zero}]
1410            lappend ans [expr {$2pi * \
1411                    ($difc2*$difc+2.0*$difa*$td)/($td*($difc2+$difa*$td))}]
1412        }
1413    }
1414    return $ans
1415}
1416
1417# convert two-theta to Q
1418proc tttoQ {twotheta hst} {
1419    set lamo2 [expr {0.5 * [histinfo $hst lam1]}]
1420    set zero [expr [histinfo $hst zero]/100.]
1421    set ans {}
1422    set cnv [expr {acos(0.)/180.}]
1423    set 2pi [expr {4.*acos(0.)}]
1424    foreach tt $twotheta {
1425        if {$tt == 0.} {
1426            lappend ans 0.
1427        } elseif {$tt == 1000.} {
1428            lappend ans 1000.
1429        } else {
1430            lappend ans [expr {$2pi * sin($cnv*($tt-$zero)) / $lamo2}]
1431        }
1432    }
1433    return $ans
1434}
1435# convert energy (edx-ray) to Q
1436# (note that this ignores the zero correction)
1437proc engtoQ {eng hst} {
1438    set lam [histinfo $hst lam1]
1439    set zero [histinfo $hst zero]
1440    set ans {}
1441    set v [expr {12.398/(2.0*[sind[expr ($lam/2.0)]])}]
1442    set 2pi [expr {4.*acos(0.)}]
1443    foreach e $eng {
1444        if {$e == 0.} {
1445            lappend ans 0.
1446        } elseif {$e == 1000.} {
1447            lappend ans 1000.
1448        } else {
1449            lappend ans [expr {$2pi * $e / $v}]
1450        }
1451    }
1452    return $ans
1453}
1454
1455proc BkgEval {terms num tlist "rlist {}"} {
1456    global expmap hst
1457    if {$num == 1} {
1458        global tmin tmax
1459        foreach x $tlist {
1460            lappend blist [chebeval $terms $x $tmin $tmax]
1461        }
1462        return $blist
1463    } elseif {$num == 2} {
1464        set ts 1
1465        if {[string range $expmap(htype_$hst) 2 2] == "T"} {
1466            catch {
1467                set line [histinfo $hst ITYP]
1468                set ts [expr 180./ [lindex $line 2]]
1469            }
1470        }
1471        foreach tof $tlist {
1472            set tofm [expr {$tof * $ts}]
1473            set bkg 0
1474            set i -1
1475            foreach t $terms {
1476                incr i
1477                set bkg [expr {$bkg + $t * cos($i * $tofm * 3.14159/180.)}]
1478            }
1479            lappend blist $bkg
1480        }
1481        return $blist
1482    } elseif {$num == 3} {
1483        set Qlist [toQ $tlist $hst]
1484        foreach Q $Qlist tofm $tlist {
1485            set i 0
1486            set j -1
1487            foreach t $terms {
1488                incr i
1489                if {$i == 1} {
1490                    set bkg $t
1491                } elseif {$i == 2} {
1492                    set bkg [expr {$bkg + $tofm * $t}]
1493                } else {
1494                    incr j
1495                    set r [lindex $rlist $j]
1496                    set QR [expr {$Q * $r}]
1497                    set bkg [expr {$bkg + $t * sin($QR)/$QR}]
1498                }
1499            }
1500            lappend blist $bkg
1501        }
1502        return $blist
1503    } elseif {$num == 4} {
1504        set Qlist [toQ $tlist $hst]
1505        foreach Q $Qlist {
1506            set i -1
1507            set QT 1
1508            foreach t $terms {
1509                incr i
1510                if {$i == 0} {
1511                    set bkg $t
1512                } else {
1513                    set QT [expr {$QT * $Q * $Q / $i}]
1514                    set bkg [expr {$bkg + $t * $QT}]
1515                }
1516            }
1517            lappend blist $bkg
1518        }
1519        return $blist
1520    } elseif {$num == 5} {
1521        set Qlist [toQ $tlist $hst]
1522        foreach Q $Qlist {
1523            set i -1
1524            set QT 1
1525            foreach t $terms {
1526                incr i
1527                if {$i == 0} {
1528                    set bkg $t
1529                } else {
1530                    set QT [expr {$QT * $i /($Q * $Q)}]
1531                    set bkg [expr {$bkg + $t * $QT}]
1532                }
1533            }
1534            lappend blist $bkg
1535        }
1536        return $blist
1537    } elseif {$num == 6} {
1538        set Qlist [toQ $tlist $hst]
1539        foreach Q $Qlist {
1540            set i 0
1541            set QT 1
1542            foreach t $terms {
1543                incr i
1544                if {$i == 1} {
1545                    set bkg $t
1546                } elseif {$i % 2} {
1547                    # odd
1548                    set QT1 [expr {1./$QT}]
1549                    set bkg [expr {$bkg + $t * $QT1}]
1550                } else {
1551                    # even
1552                    set QT [expr {2*$QT*$Q*$Q/$i}]
1553                    set QT1 $QT
1554                    set bkg [expr {$bkg + $t * $QT1}]
1555                }
1556            }
1557            lappend blist $bkg     
1558        }
1559        return $blist
1560    }
1561}
1562
1563proc backderivcal {nterms num tof "rlist {}"} {
1564    global expmap hst
1565    if {$num == 1} {
1566        global tmin tmax
1567        # rescale x
1568        set xs [expr {-1 + 2 * (1.*$tof - $tmin) / (1.*$tmax - 1.*$tmin)}]
1569        # compute the Chebyschev term Tn(xs)
1570        set deriv {}
1571        set Tpp 0
1572        set Tp 0
1573        for {set i 0} {$i < $nterms} {incr i} {
1574            if {$Tpp == $Tp && $Tp == 0} {
1575                set T 1
1576            } elseif {$Tpp == 0} {
1577                set T $xs
1578            } else {
1579                set T [expr {2. * $xs * $Tp - $Tpp}]
1580            }
1581            lappend deriv $T
1582            set Tpp $Tp
1583            set Tp $T
1584        }
1585        return $deriv
1586    } elseif {$num == 2} {
1587        set ts 1
1588        if {[string range $expmap(htype_$hst) 2 2] == "T"} {
1589            catch {
1590                set line [histinfo $hst ITYP]
1591                set ts [expr 180./ [lindex $line 2]]
1592            }
1593            set tofm [expr {$tof * $ts}]
1594        } else {
1595            set tofm $tof
1596        }
1597        set deriv {}
1598        for {set i 0} {$i < $nterms} {incr i} {
1599            lappend deriv [expr {cos($i * $tofm * 3.14159/180.)}]
1600        }
1601        return $deriv
1602    } elseif {$num == 3} {
1603        set Q [toQ $tof $hst]
1604        set j -1
1605        #set n [expr {2 + ($nterms - 2)/2}]
1606        for {set i 1} {$i <= $nterms} {incr i} {
1607            if {$i == 1} {
1608                set deriv 1
1609            } elseif {$i == 2} {
1610                lappend deriv $tof
1611            } else {
1612                incr j
1613                set r [lindex $rlist $j]
1614                set QR [expr {$Q * $r}]
1615                lappend deriv [expr {sin($QR)/$QR}]
1616            }
1617        }
1618        return $deriv
1619    } elseif {$num == 4} {
1620        set Q [toQ $tof $hst]
1621        set QT 1
1622        for {set i 0} {$i < $nterms} {incr i} {
1623            if {$i == 0} {
1624                set deriv 1
1625            } else {
1626                lappend deriv [set QT [expr {$QT * $Q * $Q / $i}]]
1627            }
1628        }
1629        return $deriv
1630    } elseif {$num == 5} {
1631        set Q [toQ $tof $hst]
1632        set QT 1
1633        for {set i 0} {$i < $nterms} {incr i} {
1634            if {$i == 0} {
1635                set deriv 1
1636            } else {
1637                lappend deriv [set QT [expr {$QT * $i /($Q * $Q)}]]
1638            }
1639        }
1640        return $deriv
1641    } elseif {$num == 6} {
1642        set Q [toQ $tof $hst]
1643        set QT 1
1644        for {set i 1} {$i <= $nterms} {incr i} {
1645            if {$i == 1} {
1646                set deriv 1
1647            } elseif {$i % 2} {
1648                # odd
1649                lappend deriv [set QT1 [expr {1./$QT}]]
1650            } else {
1651                # even
1652                set QT [expr {2*$QT*$Q*$Q/$i}]
1653                lappend deriv [set QT1 $QT]
1654            }
1655        }
1656        return $deriv
1657    }
1658}
1659
1660# evaluate the best-fit background terms to fit GSAS background functions 1-6
1661# to a set of X and Y values.
1662# num is the function number,
1663# order is the # of terms
1664# rlist is used only for function type 3; there must be (order-2)/2 values
1665proc FitBkgFunc {X Y order num "rlist {}"} {
1666    if {$num == 3} {
1667        set o [expr {2 + ($order - 2)/2}]
1668    } else {
1669        set o $order
1670    }
1671    # zero the matrix and vector
1672    for {set j 0} {$j < $o} {incr j} {
1673        set sum($j) 0.
1674        for {set i 0} {$i <= $j} {incr i} {
1675            set sum(${i}_$j) 0.
1676        }
1677    }
1678global octave
1679set octave {}
1680append octave {des = [}
1681    foreach y $Y x $X {
1682        # compute derivatives at point x
1683        set derivlist [backderivcal $o $num $x $rlist]
1684append octave " $derivlist ;\n"
1685        # compute matrix elements
1686        for {set j 0} {$j < $o} {incr j} {
1687            set Tj [lindex $derivlist $j]
1688            # weighted
1689            # set sum($j) [expr {$sum($j) + $y * $Tj / ($sigma*$sigma)}]
1690            set sum($j) [expr {$sum($j) + $y * $Tj}]
1691            for {set i 0} {$i <= $j} {incr i} {
1692                set Ti [lindex $derivlist $i]
1693                # weighted
1694                # set sum(${i}_$j) [expr {$sum(${i}_$j) + $Ti * $Tj / ($sigma * $sigma)}]
1695                set sum(${i}_$j) [expr {$sum(${i}_$j) + $Ti * $Tj}]
1696            }
1697        }
1698    }
1699    # populate the matrix & vector in La format
1700    lappend V 2 $o 0
1701    lappend A 2 $o $o
1702    for {set i 0} {$i < $o} {incr i} {
1703        lappend V $sum($i)
1704        for {set j 0} {$j < $o} {incr j} {
1705            if {$j < $i} {
1706                lappend A $sum(${j}_$i)
1707            } else {
1708                lappend A $sum(${i}_$j)
1709            }
1710        }
1711    }
1712    set termlist {}
1713    if {[catch {
1714        set termlist [lrange [La::msolve $A $V] 3 end]
1715    }]} {
1716        tk_dialog .singlar "Singular Matrix" \
1717            "Unable to fit function: singular matrix. Too many terms or something else is wrong." ""\
1718            0 OK
1719    }
1720    return $termlist
1721}
1722
1723# save the Chebyshev terms in the .EXP file
1724proc bkgSave {} {
1725    global hst termlist expgui Revision expmap expnam
1726    histinfo $hst backtype set $expgui(FitFunction)
1727    # stick the r values into the list
1728    if {$expgui(FitFunction) == 3} {
1729        set t [lrange $termlist 0 1]
1730        foreach a [lrange $termlist 2 end] b $expgui(RadiiList) {lappend t $a $b}
1731    } else {
1732        set t $termlist
1733    }
1734    histinfo $hst backterms set [llength $t]
1735    set num 0
1736    foreach v $t {
1737        set var "bterm[incr num]"
1738        histinfo $hst $var set $v
1739    }
1740    histinfo $hst bref set 0
1741    # add a history record
1742    exphistory add " BKGEDIT [lindex $Revision 1] [lindex $expmap(Revision) 1] -- [clock format [clock seconds]]"
1743    # now save the file
1744    expwrite $expnam.EXP
1745}
1746
1747#-------------------------------------------------------------------------
1748# manual zoom option
1749proc BLTmanualZoom {} {
1750    global graph
1751    catch {toplevel .zoom}
1752    eval destroy [grid slaves .zoom]
1753    raise .zoom
1754    wm title .zoom {Manual Scaling}
1755    grid [label .zoom.l1 -text minimum] -row 1 -column 2
1756    grid [label .zoom.l2 -text maximum] -row 1 -column 3
1757    grid [label .zoom.l3 -text x] -row 2 -column 1
1758    grid [label .zoom.l4 -text y] -row 3 -column 1
1759    grid [entry .zoom.xmin -textvariable graph(xmin) -width 10] -row 2 -column 2
1760    grid [entry .zoom.xmax -textvariable graph(xmax) -width 10] -row 2 -column 3
1761    grid [entry .zoom.ymin -textvariable graph(ymin) -width 10] -row 3 -column 2
1762    grid [entry .zoom.ymax -textvariable graph(ymax) -width 10] -row 3 -column 3
1763    grid [frame .zoom.b] -row 4 -column 1 -columnspan 3
1764    grid [button .zoom.b.1 -text "Set Scaling" \
1765             -command "SetManualZoom set"]  -row 4 -column 1 -columnspan 2
1766    grid [button .zoom.b.2 -text Reset \
1767            -command "SetManualZoom clear"] -row 4 -column 3
1768    grid [button .zoom.b.3 -text Close -command "destroy .zoom"] -row 4 -column 4
1769    grid rowconfigure .zoom 1 -weight 1 -pad 5
1770    grid rowconfigure .zoom 2 -weight 1 -pad 5
1771    grid rowconfigure .zoom 3 -weight 1 -pad 5
1772    grid rowconfigure .zoom 4 -weight 0 -pad 5
1773    grid columnconfigure .zoom 1 -weight 1 -pad 20
1774    grid columnconfigure .zoom 1 -weight 1
1775    grid columnconfigure .zoom 3 -weight 1 -pad 10
1776    foreach item {min min max max} \
1777            format {3   2   3   2} \
1778            axis   {x   y   x   y} {
1779        set val [$graph(blt) ${axis}axis cget -${item}]
1780        set graph(${axis}${item}) {(auto)}
1781        catch {set graph(${axis}${item}) [format %.${format}f $val]}
1782    }
1783    bind .zoom <Return> "SetManualZoom set"
1784}
1785
1786proc SetManualZoom {mode} {
1787    global graph
1788    if {$mode == "clear"} {
1789        foreach item {xmin ymin xmax ymax} {
1790            set graph($item) {(auto)}
1791        }
1792    }
1793    foreach item {xmin ymin xmax ymax} {
1794        if {[catch {expr $graph($item)}]} {
1795            set $item ""
1796        } else {
1797            set $item $graph($item)
1798        }
1799    }
1800    # reset the zoomstack
1801    catch {Blt_ZoomStack $graph(blt)}
1802    catch {$graph(blt) xaxis config -min $xmin -max $xmax}
1803    catch {$graph(blt) yaxis config -min $ymin -max $ymax}
1804    global program
1805    if {$program == "bkgedit"} {bkgEditMode ""}
1806}
1807
1808# define a binding to show the cursor location
1809proc ToggleLiveCursor {} {
1810    global box graph
1811    if {[bind $box <Any-Motion>] == ""} {
1812        .a.options.menu entryconfig $graph(CursorLabel) -label "Hide Cursor Position"
1813        pack [frame .bot -bd 2 -relief sunken] -side bottom -fill x
1814        pack [label .bot.val1 -textvariable graph(position)] -side left
1815        pack [button .bot.close -command ToggleLiveCursor -text "Close cursor display"] -side right
1816        bind $box <Any-Motion> {FormatLiveCursor %x %y}
1817    } else {
1818        .a.options.menu entryconfig $graph(CursorLabel) -label "Show Cursor Position"
1819        destroy .bot
1820        bind $box <Any-Motion> {}
1821    }
1822}
1823proc FormatLiveCursor {x y} {
1824    global graph
1825    set graph(position) \
1826            "x=[format %.3f [$graph(blt) xaxis invtransform $x]] y=[format %.3f [$graph(blt) yaxis invtransform $y]]"
1827}
1828#-------------------------------------------------------------------------
1829
1830
1831# override options with locally defined values
1832if [file exists [file join $expgui(scriptdir) localconfig]] {
1833    source [file join $expgui(scriptdir) localconfig]
1834}
1835if [file exists [file join ~ .gsas_config]] {
1836    source [file join ~ .gsas_config]
1837}
1838SetTkDefaultOptions $expgui(font)
1839
1840if [file executable [file join $expgui(gsasexe) $expgui(tcldump)]] {
1841    set expgui(tcldump) [file join $expgui(gsasexe) $expgui(tcldump)]
1842} else {
1843    set expgui(tcldump) {}
1844}
1845
1846# vectors
1847if [catch {
1848    foreach vec {xvec obsvec calcvec bckvec diffvec refposvec wifdvec} {
1849        vector $vec
1850        $vec notify never
1851    }
1852} errmsg] {
1853    MyMessageBox -parent . -title "BLT Error" \
1854            -message "BLT Setup Error: could not define vectors \
1855(msg: $errmsg). \
1856$program cannot be run without vectors." \
1857            -helplink "expgui.html blt" \
1858            -icon error -type Skip -default skip
1859    exit
1860}
1861
1862# create the graph
1863if [catch {
1864    set box [graph .g -plotbackground white]
1865    set graph(blt) $box
1866} errmsg] {
1867    MyMessageBox -parent . -title "BLT Error" \
1868            -message "BLT Setup Error: could not create a graph \
1869(error msg: $errmsg). \
1870There is a problem with the setup of BLT on your system. \
1871See the expgui.html file for more info." \
1872            -helplink "expgui.html blt" \
1873            -icon warning -type Exit -default "exit"
1874    exit
1875}
1876if [catch {
1877    Blt_ZoomStack $box
1878} errmsg] {
1879    MyMessageBox -parent . -title "BLT Error" \
1880            -message "BLT Setup Error: could not access a Blt_ routine \
1881(msg: $errmsg). \
1882The pkgIndex.tcl is probably not loading bltGraph.tcl.
1883See the expgui.html file for more info." \
1884        -helplink "expgui.html blt" \
1885        -icon warning -type {"Limp Ahead"} -default "limp Ahead"
1886}
1887# modify zoom so that y2axis is not zoomed in for blt2.4u+
1888catch {
1889    regsub -all y2axis [info body blt::PushZoom] " " b1
1890    proc blt::PushZoom {graph} $b1
1891}
1892
1893$box element create 0 -xdata xvec -ydata wifdvec -color $graph(color_chi2) \
1894        -line 3 -symbol none -label "Chi2" -mapy y2
1895$box element create 1 -label bckgr -symbol none 
1896$box element config 1 -xdata xvec -ydata bckvec -color $graph(color_bkg)
1897$box element create 3 -color $graph(color_obs) -linewidth 0 -label Obs \
1898        -symbol $peakinfo(obssym) \
1899        -pixels [expr 0.125 * $peakinfo(obssize)]i
1900$box element create 2 -label Calc -color $graph(color_calc) -symbol none 
1901$box element create 4 -label diff -color $graph(color_diff) -symbol none 
1902
1903if {$program == "liveplot"} {
1904    $box y2axis config -min 0 -title {Cumulative Chi Squared}
1905} elseif {$program == "bkgedit"}  {
1906    eval $box element config 0 $graph(ElementHideOption)
1907    eval $box y2axis config $graph(ElementHideOption)
1908    $box element config 0 -label ""
1909    eval $box element config 1 $graph(ElementHideOption)
1910    $box element config 1 -label ""
1911    eval $box element config 4 $graph(ElementHideOption)
1912    $box element config 4 -label ""
1913    $box element create 11
1914    $box element create 12
1915    $box element configure 12  -color $graph(color_input) \
1916            -pixels [expr 0.125 * $peakinfo(inpsize)]i \
1917            -line 0 -symbol $peakinfo(inpsym) -label "bkg pts"
1918    $box element configure 11 -color $graph(color_fit) \
1919            -symbol none -label "bkg fit" -dashes 5 -line 2
1920    $box element show "3 2 11 12"
1921}
1922$box element config 3 -xdata xvec -ydata obsvec
1923$box element config 2 -xdata xvec -ydata calcvec
1924$box element config 4 -xdata xvec -ydata diffvec
1925
1926if {$expgui(tcldump) != ""} {
1927    bind . <Key-h> "lblhkl $box %x"
1928    bind . <Key-H> "lblhkl $box %x"
1929    bind . <Key-a> "lblhkl $box all"
1930    bind . <Key-A> "lblhkl $box all"
1931    bind . <Key-d> "delallhkllbl $box"
1932    bind . <Key-D> "delallhkllbl $box"
1933    if {[bind bltZoomGraph] != ""} {
1934        bind bltZoomGraph <Shift-Button-1> "lblhkl $box %x"
1935        bind bltZoomGraph <Shift-Button-3> "delallhkllbl %W"
1936    } else {
1937        bind $box <Shift-Button-1> "lblhkl $box %x"
1938        bind $box <Shift-Button-3> "delallhkllbl %W"
1939    }
1940} else {
1941    $box element config 1 -label ""
1942    eval $box element config 4 $graph(ElementHideOption)
1943}
1944bind . <Key-z> {BLTmanualZoom}
1945bind . <Key-Z> {BLTmanualZoom}
1946
1947$box yaxis config -title {}
1948setlegend $box $graph(legend)
1949
1950frame .a -bd 3 -relief groove
1951pack [menubutton .a.file -text File -underline 0 -menu .a.file.menu] -side left
1952menu .a.file.menu
1953.a.file.menu add cascade -label Tickmarks -menu .a.file.menu.tick
1954menu .a.file.menu.tick
1955.a.file.menu add cascade -label Histogram -menu .a.file.menu.hist -state disabled
1956.a.file.menu add command -label "Update Plot" \
1957        -command {set cycle [getcycle];readdata .g}
1958.a.file.menu add cascade -label "Export plot" -menu .a.file.menu.export
1959menu .a.file.menu.export
1960.a.file.menu.export add command -label "to PostScript" \
1961        -command makepostscriptout
1962if {$blt_version > 2.3 && $blt_version != 8.0} {
1963    source [file join $expgui(scriptdir) graceexport.tcl]
1964    .a.file.menu.export add command -label "to Grace" -command exportgrace
1965}
1966.a.file.menu add command -label Quit -command "destroy ."
1967
1968pack [menubutton .a.options -text Options -underline 0 -menu .a.options.menu] \
1969        -side left   
1970menu .a.options.menu
1971.a.options.menu add cascade -label "Configure Tickmarks" -menu .a.options.menu.tick
1972menu .a.options.menu.tick
1973.a.options.menu.tick add radiobutton -label "Manual Placement" \
1974        -value 0 -variable expgui(autotick) -command plotdata
1975.a.options.menu.tick add radiobutton -label "Auto locate" \
1976        -value 1 -variable expgui(autotick) -command plotdata
1977.a.options.menu.tick add separator
1978.a.options.menu.tick add command -label "Label by name" \
1979        -command {
1980    foreach p $expmap(phaselist) {
1981        # 20 characters, max
1982        set graph(label$p) [string range [phaseinfo $p name] 0 19]
1983        plotdata
1984    }
1985}
1986.a.options.menu.tick add separator
1987
1988if {$program == "liveplot"} {
1989    .a.options.menu add command -label "Obs symbol" -command getsymopts
1990} else {
1991    .a.options.menu add cascade -label "Symbol Type" -menu .a.options.menu.sym
1992    menu .a.options.menu.sym
1993    foreach var {obs inp} lbl {Observed "Input bkg"} {
1994        .a.options.menu.sym add command -label $lbl -command "getsymopts $var"
1995    }
1996}
1997.a.options.menu add cascade -label "Symbol color" -menu .a.options.menu.color
1998menu .a.options.menu.color
1999set l1 {obs calc diff bkg chi2}
2000set l2 {Observed Calculated Obs-Calc Background Cumulative-Chi2}
2001if {$program != "liveplot"} {
2002    lappend l1 input fit
2003    lappend l2 "Input points" "bkg fit"
2004}
2005   
2006foreach var $l1 lbl $l2 {
2007    .a.options.menu.color add command -label $lbl \
2008        -command "set graph(color_$var) \[tk_chooseColor -initialcolor \$graph(color_$var) -title \"Choose \$lbl color\"]; plotdata"
2009}
2010if {$expgui(tcldump) != "" && $program == "liveplot"} {
2011    .a.options.menu add cascade -label "X units" -menu .a.options.menu.xunits
2012    menu .a.options.menu.xunits
2013    .a.options.menu.xunits add radiobutton -label "As collected" \
2014            -variable graph(xunits) -value 0 \
2015            -command {set cycle [getcycle];readdata .g}
2016    .a.options.menu.xunits add radiobutton -label "d-space" \
2017            -variable graph(xunits) -value 1 \
2018            -command {set cycle [getcycle];readdata .g}
2019    .a.options.menu.xunits add radiobutton -label "Q" \
2020            -variable graph(xunits) -value 2 \
2021            -command {set cycle [getcycle];readdata .g}
2022    .a.options.menu add cascade -label "Y units" -menu .a.options.menu.yunits
2023    menu .a.options.menu.yunits
2024    .a.options.menu.yunits add radiobutton -label "As collected" \
2025            -variable graph(yunits) -value 0 \
2026            -command {set cycle [getcycle];readdata .g}
2027    .a.options.menu.yunits add radiobutton -label "Normalized" \
2028            -variable graph(yunits) -value 1 \
2029            -command {set cycle [getcycle];readdata .g}
2030    .a.options.menu add command -label "HKL labeling" -command setlblopts
2031    .a.options.menu add checkbutton -label "Subtract background" \
2032            -variable graph(backsub) \
2033            -command {set cycle [getcycle];readdata .g}
2034} else {
2035    set graph(xunits) 0
2036}
2037   
2038.a.options.menu add checkbutton -label "Include legend" \
2039        -variable graph(legend) \
2040        -command {setlegend $box $graph(legend)}
2041.a.options.menu add command -label "Show Cursor Position" \
2042        -command ToggleLiveCursor
2043set graph(CursorLabel) [.a.options.menu index "Show Cursor Position"]
2044.a.options.menu add command -label "Set PS output" -command setpostscriptout
2045.a.options.menu add cascade -menu  .a.options.menu.font \
2046        -label "Screen font"
2047menu .a.options.menu.font
2048foreach f {10 11 12 13 14 16 18 20 22} {
2049    .a.options.menu.font add radiobutton \
2050            -command {SetTkDefaultOptions $expgui(font); ResizeFont .} \
2051        -label $f -value $f -variable expgui(font) -font "Helvetica -$f"
2052}
2053if {$program == "liveplot"} {
2054    .a.options.menu add checkbutton -label "Raise on update" \
2055            -variable graph(autoraise)
2056    .a.options.menu add checkbutton -label "Cumulative Chi2" \
2057            -variable graph(chi2) -command ShowCumulativeChi2
2058    .a.options.menu add command -label "Save Options" -underline 1 \
2059            -command "SaveOptions"
2060    ShowCumulativeChi2
2061} elseif {$program == "bkgedit"}  {
2062    catch {pack [frame .bkg -bd 3 -relief sunken] -side bottom -fill both}
2063#    grid [label .bkg.top -text "Background Point Editing"] \
2064#           -col 0 -row 0 -columnspan 4
2065#    grid [button .bkg.help -text Help -bg yellow \
2066#           -command "MakeWWWHelp liveplot.html bkgedit"] \
2067#           -column 5 -row 0 -rowspan 2 -sticky n
2068   
2069    grid [frame .bkg.l -bd 3 -relief groove] \
2070            -col 0 -row 1 -columnspan 2 -sticky nse
2071    grid [label .bkg.l.1 -text "Mouse click\naction"] -col 0 -row 0
2072    foreach c {1 2 3} l {zoom add delete} {
2073        grid [button .bkg.l.b$c -text $l -command "bkgEditMode $c"] \
2074                -col $c -row 0
2075    }
2076    # leave a small blank space
2077    grid columnconfigure .bkg 2 -pad 0 -min 10
2078    grid [frame .bkg.f -bd 3 -relief groove] \
2079            -col 3 -row 1 -columnspan 2 -sticky nsw
2080    grid [button .bkg.f.fit1 -text "Fit" -command {bkgFit .bkg.f.fit1}] \
2081            -col 1 -row 1
2082    grid [label .bkg.f.tl -text "with"] -col 3 -row 1
2083    set termmenu [tk_optionMenu .bkg.f.terms expgui(FitOrder) 0]
2084    grid .bkg.f.terms -col 4 -row 1
2085    grid [label .bkg.f.tl1 -text "terms"] -col 5 -row 1
2086
2087    grid [frame .bkg.c1 -bd 3 -relief groove] \
2088            -col 0 -row 5 -rowspan 2 -sticky nsew
2089    grid [label .bkg.c1.0 -text "Background\nfunction #"] -col 0 -row 0
2090    set bkgmenu [tk_optionMenu .bkg.c1.1 expgui(FitFunction) stuff]
2091    grid .bkg.c1.1 -col 0 -row 1
2092    $bkgmenu delete 0 end
2093    foreach item {
2094        "1 - Shifted Chebyschev polynomial"
2095        "2 - Cosine Fourier series"
2096        "3 - Radial distribution peaks"
2097        "4 - Power series in Q**2n/n!"
2098        "5 - Power series in n!/Q**2n"
2099        "6 - Power series in Q**2n/n! and n!/Q**2n"
2100    } {
2101        set val [lindex $item 0]
2102        $bkgmenu insert end radiobutton -variable expgui(FitFunction) \
2103                -label $item -value $val \
2104                -command "set termlist {};BkgFillTermBoxes nosave"
2105    }
2106    set expgui(FitFunction) 1
2107
2108    grid [canvas .bkg.canvas \
2109            -scrollregion {0 0 5000 500} -width 0 -height 0 \
2110            -xscrollcommand ".bkg.scroll set"] \
2111            -column 1 -row 5 -columnspan 3 -sticky nsew
2112    grid [scrollbar .bkg.scroll -command ".bkg.canvas xview" \
2113            -orient horizontal] -column 1 -row 6 -columnspan 3 -sticky nsew
2114    grid [button .bkg.cw -text "Save in\nEXP file\n& Exit" \
2115            -command "bkgSave;exit"] \
2116            -col 4 -columnspan 2 -row 5 -rowspan 2 -sticky ns
2117
2118    grid [frame .bkg.bl -bd 3 -relief groove] \
2119            -col 0 -row 3 -rowspan 2 -sticky nsew
2120    grid [label .bkg.bl.1 -text "Background\npoints"] -col 0 -row 0
2121    grid [canvas .bkg.bc \
2122            -scrollregion {0 0 5000 500} -width 0 -height 0 \
2123            -xscrollcommand ".bkg.bs set"] \
2124            -column 1 -row 3 -columnspan 5 -sticky nsew
2125    grid [scrollbar .bkg.bs -command ".bkg.bc xview" -orient horizontal] \
2126            -column 1 -row 4 -columnspan 5 -sticky nsew
2127
2128    grid columnconfigure .bkg 1 -weight 1
2129    grid columnconfigure .bkg 2 -weight 1
2130    grid columnconfigure .bkg 3 -weight 1
2131    grid rowconfigure .bkg 3 -weight 1
2132    grid rowconfigure .bkg 5 -weight 1
2133    .g config -title ""
2134}
2135
2136pack [menubutton .a.help -text Help -underline 0 -menu .a.help.menu] -side right
2137menu .a.help.menu -tearoff 0
2138if {$program == "bkgedit"}  {
2139    .a.help.menu add command -command "MakeWWWHelp liveplot.html bkgedit" \
2140            -label "Web page"
2141} else {
2142    .a.help.menu add command -command "MakeWWWHelp liveplot.html" \
2143            -label "Web page"
2144}
2145.a.help.menu add command -command aboutliveplot -label About
2146
2147pack .a -side top -fill both
2148pack $box -fill both -expand yes
2149
2150# add the extra options
2151set fl [file join $expgui(scriptdir) icddcmd.tcl]
2152if [file exists $fl] {source $fl}
2153set fl [file join $expgui(scriptdir) cellgen.tcl]
2154if [file exists $fl] {source $fl}
2155
2156expload $expnam.EXP
2157mapexp
2158
2159# fill the histogram menu
2160if {[llength $expmap(powderlist)] > 15} {
2161    set expgui(plotlist) {}
2162    .a.file.menu entryconfigure Histogram -state normal
2163    menu .a.file.menu.hist
2164    set i 0
2165    foreach num [lsort -integer $expmap(powderlist)] {
2166        incr i
2167        # for now include, but disable histograms
2168        set state disabled
2169        if {[string range $expmap(htype_$num) 3 3] != "*"} {
2170            set state normal
2171            lappend expgui(plotlist) $num
2172        }
2173        if {$i == 1} {
2174            set num1 $num
2175            menu .a.file.menu.hist.$num1
2176        }
2177        .a.file.menu.hist.$num1 add radiobutton -label $num -value $num \
2178                -variable hst -state $state \
2179                -command {set cycle [getcycle];readdata .g}
2180        if {$i >= 10} {
2181            set i 0
2182            .a.file.menu.hist add cascade -label "$num1-$num" \
2183                    -menu .a.file.menu.hist.$num1
2184        }
2185    }
2186    if {$i != 0} {
2187        .a.file.menu.hist add cascade -label "$num1-$num" \
2188                -menu .a.file.menu.hist.$num1
2189    }
2190} elseif {[llength $expmap(powderlist)] > 1} {
2191    set expgui(plotlist) {}
2192    .a.file.menu entryconfigure Histogram -state normal
2193    menu .a.file.menu.hist
2194    foreach num [lsort -integer $expmap(powderlist)] {
2195        # for now include, but disable unprocessed histograms
2196        set state disabled
2197        if {[string range $expmap(htype_$num) 3 3] != "*"} {
2198            set state normal
2199            lappend expgui(plotlist) $num
2200        }
2201        .a.file.menu.hist add radiobutton -label $num -value $num \
2202                -variable hst -state $state \
2203                -command {set cycle [getcycle];readdata .g}
2204    }
2205} else {
2206    set expgui(plotlist) [lindex $expmap(powderlist) 0]
2207}
2208
2209foreach num $expmap(phaselist) {
2210    .a.file.menu.tick add checkbutton -label "Phase $num" \
2211            -variable  peakinfo(flag$num) \
2212            -command plotdata
2213    bind . <Key-$num> ".a.file.menu.tick invoke $num"
2214    .a.options.menu.tick add command -label "Phase $num opts" \
2215            -command "minioptionsbox $num"
2216}
2217
2218# N = load next histogram
2219bind . <Key-n> {
2220    set i [lsearch $expgui(plotlist) $hst]
2221    incr i
2222    if {$i >= [llength $expgui(plotlist)]} {set i 0}
2223    set hst [lindex $expgui(plotlist) $i]
2224    set cycle [getcycle];readdata .g
2225}
2226bind . <Key-N> {
2227    set i [lsearch $expgui(plotlist) $hst]
2228    incr i
2229    if {$i >= [llength $expgui(plotlist)]} {set i 0}
2230    set hst [lindex $expgui(plotlist) $i]
2231    set cycle [getcycle];readdata .g
2232}
2233bind . <Key-l> {ToggleLiveCursor}
2234bind . <Key-L> {ToggleLiveCursor}
2235updateifnew
2236donewaitmsg
2237trace variable peakinfo w plotdataupdate
Note: See TracBrowser for help on using the repository browser.