source: trunk/gui/scripts/analyzer.tcl @ 8

Last change on this file since 8 was 8, checked in by mmc, 16 years ago

Updated the code to the latest Rappture XML conventions, and fixed
up the moleculeViewer and energyLevels viewer. Everything works
properly now with the new app-huckel project. You can load up
the molecule viewer, rotate molecules, and view their energy levels.

File size: 12.4 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: analyzer - output area for Rappture
3#
4#  This widget acts as the output side of a Rappture application.
5#  When the input has changed, it displays a Simulate button that
6#  launches the simulation.  When a simulation is running, this
7#  area shows status.  When it is finished, the results appear
8#  in place of the button, according to the specs in the <analyze>
9#  XML data.
10# ======================================================================
11#  AUTHOR:  Michael McLennan, Purdue University
12#  Copyright (c) 2004  Purdue Research Foundation, West Lafayette, IN
13# ======================================================================
14package require Itk
15package require BLT
16
17option add *Analyzer.textFont \
18    -*-helvetica-medium-r-normal-*-*-120-* widgetDefault
19
20itcl::class Rappture::Analyzer {
21    inherit itk::Widget
22
23    itk_option define -tool tool Tool ""
24    itk_option define -device device Device ""
25    itk_option define -analysis analysis Analysis ""
26    itk_option define -holdwindow holdWindow HoldWindow ""
27
28    constructor {args} { # defined below }
29    destructor { # defined below }
30
31    public method simulate {}
32    public method reset {}
33    public method load {file}
34
35    protected method _fixResult {}
36
37    private variable _run ""           ;# results from last run
38    private variable _control "manual" ;# start mode
39    private variable _widgets          ;# maps analyze section => widget
40
41    private common job                 ;# array var used for blt::bgexec jobs
42}
43                                                                               
44itk::usual Analyzer {
45    keep -background -cursor foreground -font
46}
47
48# ----------------------------------------------------------------------
49# CONSTRUCTOR
50# ----------------------------------------------------------------------
51itcl::body Rappture::Analyzer::constructor {args} {
52    itk_component add notebook {
53        Rappture::Notebook $itk_interior.nb
54    }
55    pack $itk_interior.nb -expand yes -fill both
56
57    # ------------------------------------------------------------------
58    # SIMULATION PAGE
59    # ------------------------------------------------------------------
60    set w [$itk_component(notebook) insert end simulate]
61    frame $w.cntls
62    pack $w.cntls -side top -fill x -padx {20 2}
63
64    itk_component add simulate {
65        button $w.cntls.sim -text "Simulate" \
66            -command [itcl::code $this simulate]
67    }
68    pack $itk_component(simulate) -side left
69
70    itk_component add status {
71        label $w.cntls.info -width 1 -text "" -anchor w
72    } {
73        usual
74        rename -font -textfont textFont Font
75    }
76    pack $itk_component(status) -side left -expand yes -fill both
77
78    Rappture::Scroller $w.info -xscrollmode off -yscrollmode auto
79    pack $w.info -expand yes -fill both -padx {20 2} -pady {20 2}
80    itk_component add info {
81        text $w.info.text -width 1 -height 1 -wrap word \
82            -borderwidth 0 -highlightthickness 0 \
83            -state disabled
84    } {
85        usual
86        ignore -borderwidth -relief
87        rename -font -textfont textFont Font
88    }
89    $w.info contents $w.info.text
90
91    # ------------------------------------------------------------------
92    # ANALYZE PAGE
93    # ------------------------------------------------------------------
94    set w [$itk_component(notebook) insert end analyze]
95
96    itk_component add resultselector {
97        Rappture::Combobox $w.sel -width 30 -editable no
98    } {
99        usual
100        rename -font -textfont textFont Font
101    }
102    pack $itk_component(resultselector) -side top -fill x -padx {20 2}
103    bind $itk_component(resultselector) <<Value>> [itcl::code $this _fixResult]
104
105    itk_component add results {
106        Rappture::Notebook $w.nb
107    }
108    pack $itk_component(results) -expand yes -fill both -pady 4
109
110    eval itk_initialize $args
111    reset
112}
113
114# ----------------------------------------------------------------------
115# DESTRUCTOR
116# ----------------------------------------------------------------------
117itcl::body Rappture::Analyzer::destructor {} {
118    if {$_run != ""} {
119        itcl::delete object $_run
120    }
121}
122
123# ----------------------------------------------------------------------
124# USAGE: simulate
125#
126# If the simulation page is showing, this kicks off the simulator
127# by executing the tool.command associated with the -tool.  While
128# the simulation is running, it shows status.  When the simulation is
129# finished, it switches automatically to "analyze" mode and shows
130# the results.
131# ----------------------------------------------------------------------
132itcl::body Rappture::Analyzer::simulate {} {
133    if {[$itk_component(notebook) current] == "simulate"} {
134        $itk_component(status) configure -text "Running simulation..."
135        $itk_component(simulate) configure -text "Abort" \
136            -command {set ::Rappture::Analyzer::job(control) abort}
137
138        set job(control) ""
139        set job(error) ""
140
141        # if the hold window is set, then put up a busy cursor
142        if {$itk_option(-holdwindow) != ""} {
143            blt::busy hold $itk_option(-holdwindow)
144            raise $itk_component(hull)
145            update
146        }
147
148        # write out the driver.xml file for the tool
149        set status [catch {
150            set fid [open driver.xml w]
151            puts $fid "<?xml version=\"1.0\"?>"
152            set xml [$itk_option(-tool) xml]
153            set xml2 [$itk_option(-device) xml]
154            regsub -all {&} $xml2 {\\\&} xml2
155            regsub {</run>} $xml "$xml2</run>" xml
156            puts $fid $xml
157            close $fid
158        } result]
159
160        # execute the tool using the path from the tool description
161        if {$status == 0} {
162            set cmd [$itk_option(-tool) get tool.command]
163
164            set status [catch {eval blt::bgexec \
165                ::Rappture::Analyzer::job(control) \
166                -output ::Rappture::Analyzer::job(output) \
167                -error ::Rappture::Analyzer::job(error) $cmd} result]
168        }
169
170        # read back the results from run.xml
171        if {$status == 0} {
172            set status [catch {load run.xml} result]
173        }
174
175        # back to normal
176        if {$itk_option(-holdwindow) != ""} {
177            blt::busy release $itk_option(-holdwindow)
178        }
179        $itk_component(status) configure -text ""
180        $itk_component(simulate) configure -text "Simulate" \
181            -command [itcl::code $this simulate]
182
183        # if anything went wrong, tell the user; otherwise, analyze
184        if {[regexp {^KILLED} $job(control)]} {
185            # job aborted -- do nothing
186        } elseif {$status != 0} {
187            $itk_component(info) configure -state normal
188            $itk_component(info) delete 1.0 end
189            $itk_component(info) insert end "Problem launching job:\n"
190            if {[string length $job(error)] > 0} {
191                $itk_component(info) insert end $job(error)
192            } else {
193                $itk_component(info) insert end $result
194            }
195            $itk_component(info) configure -state disabled
196        } else {
197            $itk_component(notebook) current analyze
198        }
199    }
200}
201
202# ----------------------------------------------------------------------
203# USAGE: reset
204#
205# Used to reset the analyzer whenever the input to a simulation has
206# changed.  Sets the mode back to "simulate", so the user has to
207# simulate again to see the output.  If the <start> option is set
208# to "auto", the simulation is invoked immediately.
209# ----------------------------------------------------------------------
210itcl::body Rappture::Analyzer::reset {} {
211    $itk_component(notebook) current simulate
212
213    # if control mode is "auto", then simulate right away
214    if {[string match auto* $_control]} {
215        simulate
216    }
217}
218
219# ----------------------------------------------------------------------
220# USAGE: load <file>
221#
222# Used to reset the analyzer whenever the input to a simulation has
223# changed.  Sets the mode back to "simulate", so the user has to
224# simulate again to see the output.
225# ----------------------------------------------------------------------
226itcl::body Rappture::Analyzer::load {file} {
227    # clear any old results
228    if {$_run != ""} {
229        itcl::delete object $_run
230        set _run ""
231    }
232
233    # try to load new results from the given file
234    set _run [Rappture::library $file]
235
236    # go through the analysis and create widgets to display results
237    foreach item [array names _widgets] {
238        $_widgets($item) configure -output $_run
239    }
240}
241
242# ----------------------------------------------------------------------
243# USAGE: _fixResult
244#
245# Used internally to change the result page being displayed whenever
246# the user selects a page from the results combobox.
247# ----------------------------------------------------------------------
248itcl::body Rappture::Analyzer::_fixResult {} {
249    set page [$itk_component(resultselector) value]
250    set page [$itk_component(resultselector) translate $page]
251    $itk_component(results) current $page
252}
253
254# ----------------------------------------------------------------------
255# CONFIGURATION OPTION: -tool
256#
257# Set to the Rappture::library object representing the tool being
258# run in this analyzer.
259# ----------------------------------------------------------------------
260itcl::configbody Rappture::Analyzer::tool {
261    if {![Rappture::library isvalid $itk_option(-tool)]} {
262        error "bad value \"$itk_option(-tool)\": should be Rappture::library"
263    }
264
265    $itk_component(info) configure -state normal
266    $itk_component(info) delete 1.0 end
267    $itk_component(info) insert end [$itk_option(-tool) get executable.about]
268    $itk_component(info) configure -state disabled
269}
270
271# ----------------------------------------------------------------------
272# CONFIGURATION OPTION: -device
273#
274# Set to the Rappture::library object representing the device being
275# run in this analyzer.
276# ----------------------------------------------------------------------
277itcl::configbody Rappture::Analyzer::device {
278    if {$itk_option(-device) != ""
279          && ![Rappture::library isvalid $itk_option(-device)]} {
280        error "bad value \"$itk_option(-device)\": should be Rappture::library"
281    }
282    reset
283}
284
285# ----------------------------------------------------------------------
286# CONFIGURATION OPTION: -analysis
287#
288# Set to the Rappture::library object representing the analysis that
289# should be shown in this analyzer.
290# ----------------------------------------------------------------------
291itcl::configbody Rappture::Analyzer::analysis {
292    if {![Rappture::library isvalid $itk_option(-analysis)]} {
293        error "bad value \"$itk_option(-analysis)\": should be Rappture::library"
294    }
295    set _control [$itk_option(-analysis) get control]
296
297    # go through the analysis and create widgets to display results
298    $itk_component(results) delete -all
299    catch {unset _widgets}
300
301    set counter 0
302    foreach item [$itk_option(-analysis) children] {
303        switch -glob -- $item {
304            xyplot* {
305                set name "page[incr counter]"
306                set label [$itk_option(-analysis) get $item.label]
307                if {$label == ""} { set label $name }
308
309                set page [$itk_component(results) insert end $name]
310                $itk_component(resultselector) choices insert end \
311                    $name $label
312
313                set _widgets($item) [Rappture::Xyplot $page.#auto \
314                    -layout [$itk_option(-analysis) element -flavor object $item]]
315                pack $_widgets($item) -expand yes -fill both
316            }
317            elevels* {
318                set name "page[incr counter]"
319
320                set page [$itk_component(results) insert end $name]
321                $itk_component(resultselector) choices insert end \
322                    $name "Energy Levels"
323
324                set _widgets($item) [Rappture::EnergyLevels $page.#auto \
325                    -layout [$itk_option(-analysis) element -flavor object $item]]
326                pack $_widgets($item) -expand yes -fill both
327            }
328        }
329    }
330
331    # if there is only one page, take down the selector
332    if {[$itk_component(resultselector) choices size] <= 1} {
333        pack forget $itk_component(resultselector)
334    } else {
335        pack $itk_component(resultselector) -before $itk_component(results) \
336            -side top -fill x -padx {20 2}
337    }
338
339    # show the first page by default
340    set first [$itk_component(resultselector) choices get -label 0]
341    if {$first != ""} {
342        $itk_component(results) current page1
343        $itk_component(resultselector) value $first
344    }
345}
Note: See TracBrowser for help on using the repository browser.