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

Last change on this file since 1 was 1, checked in by mmc, 19 years ago

initial import

File size: 11.9 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 executable.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
140        # if the hold window is set, then put up a busy cursor
141        if {$itk_option(-holdwindow) != ""} {
142            blt::busy hold $itk_option(-holdwindow)
143            raise $itk_component(hull)
144            update
145        }
146
147        # write out the driver.xml file for the tool
148        set status [catch {
149            set fid [open driver.xml w]
150            puts $fid "<?xml version=\"1.0\"?>"
151            set xml [$itk_option(-tool) xml]
152            set xml2 [$itk_option(-device) xml]
153            regsub -all {&} $xml2 {\\\&} xml2
154            regsub {</tool>} $xml "$xml2</tool>" xml
155            puts $fid $xml
156            close $fid
157        } result]
158
159        # execute the tool using the path from the tool description
160        if {$status == 0} {
161            set cmd [$itk_option(-tool) get executable.command]
162
163            set status [catch {eval blt::bgexec \
164                ::Rappture::Analyzer::job(control) \
165                -output ::Rappture::Analyzer::job(output) \
166                -error ::Rappture::Analyzer::job(error) $cmd} result]
167        }
168
169        # read back the results from run.xml
170        if {$status == 0} {
171            set status [catch {load run.xml} result]
172        }
173
174        # back to normal
175        if {$itk_option(-holdwindow) != ""} {
176            blt::busy release $itk_option(-holdwindow)
177        }
178        $itk_component(status) configure -text ""
179        $itk_component(simulate) configure -text "Simulate" \
180            -command [itcl::code $this simulate]
181
182        # if anything went wrong, tell the user; otherwise, analyze
183        if {[regexp {^KILLED} $job(control)]} {
184            # job aborted -- do nothing
185        } elseif {$status != 0} {
186            $itk_component(info) configure -state normal
187            $itk_component(info) delete 1.0 end
188            $itk_component(info) insert end "Problem launching job:\n"
189            if {[string length $job(error)] > 0} {
190                $itk_component(info) insert end $job(error)
191            } else {
192                $itk_component(info) insert end $result
193            }
194            $itk_component(info) configure -state disabled
195        } else {
196            $itk_component(notebook) current analyze
197        }
198    }
199}
200
201# ----------------------------------------------------------------------
202# USAGE: reset
203#
204# Used to reset the analyzer whenever the input to a simulation has
205# changed.  Sets the mode back to "simulate", so the user has to
206# simulate again to see the output.  If the <start> option is set
207# to "auto", the simulation is invoked immediately.
208# ----------------------------------------------------------------------
209itcl::body Rappture::Analyzer::reset {} {
210    $itk_component(notebook) current simulate
211
212    # if control mode is "auto", then simulate right away
213    if {$_control == "auto"} {
214        simulate
215    }
216}
217
218# ----------------------------------------------------------------------
219# USAGE: load <file>
220#
221# Used to reset the analyzer whenever the input to a simulation has
222# changed.  Sets the mode back to "simulate", so the user has to
223# simulate again to see the output.
224# ----------------------------------------------------------------------
225itcl::body Rappture::Analyzer::load {file} {
226    # clear any old results
227    if {$_run != ""} {
228        itcl::delete object $_run
229        set _run ""
230    }
231
232    # try to load new results from the given file
233    set _run [Rappture::Library::open $file]
234
235    # go through the analysis and create widgets to display results
236    foreach item [array names _widgets] {
237        $_widgets($item) configure -run $_run
238    }
239}
240
241# ----------------------------------------------------------------------
242# USAGE: _fixResult
243#
244# Used internally to change the result page being displayed whenever
245# the user selects a page from the results combobox.
246# ----------------------------------------------------------------------
247itcl::body Rappture::Analyzer::_fixResult {} {
248    set page [$itk_component(resultselector) value]
249    set page [$itk_component(resultselector) translate $page]
250    $itk_component(results) current $page
251}
252
253# ----------------------------------------------------------------------
254# CONFIGURATION OPTION: -tool
255#
256# Set to the Rappture::Library object representing the tool being
257# run in this analyzer.
258# ----------------------------------------------------------------------
259itcl::configbody Rappture::Analyzer::tool {
260    if {![Rappture::Library::valid $itk_option(-tool)]} {
261        error "bad value \"$itk_option(-tool)\": should be Rappture::Library"
262    }
263
264    $itk_component(info) configure -state normal
265    $itk_component(info) delete 1.0 end
266    $itk_component(info) insert end [$itk_option(-tool) get executable.about]
267    $itk_component(info) configure -state disabled
268}
269
270# ----------------------------------------------------------------------
271# CONFIGURATION OPTION: -device
272#
273# Set to the Rappture::Library object representing the device being
274# run in this analyzer.
275# ----------------------------------------------------------------------
276itcl::configbody Rappture::Analyzer::device {
277    if {$itk_option(-device) != ""
278          && ![Rappture::Library::valid $itk_option(-device)]} {
279        error "bad value \"$itk_option(-device)\": should be Rappture::Library"
280    }
281    reset
282}
283
284# ----------------------------------------------------------------------
285# CONFIGURATION OPTION: -analysis
286#
287# Set to the Rappture::Library object representing the analysis that
288# should be shown in this analyzer.
289# ----------------------------------------------------------------------
290itcl::configbody Rappture::Analyzer::analysis {
291    if {![Rappture::Library::valid $itk_option(-analysis)]} {
292        error "bad value \"$itk_option(-analysis)\": should be Rappture::Library"
293    }
294    set _control [$itk_option(-analysis) get control]
295
296    # go through the analysis and create widgets to display results
297    $itk_component(results) delete -all
298    catch {unset _widgets}
299
300    set counter 0
301    foreach item [$itk_option(-analysis) get -children] {
302        switch -glob -- $item {
303            xyplot* {
304                set name "page[incr counter]"
305                set label [$itk_option(-analysis) get $item.label]
306                if {$label == ""} { set label $name }
307
308                set page [$itk_component(results) insert end $name]
309                $itk_component(resultselector) choices insert end \
310                    $name $label
311
312                set _widgets($item) [Rappture::Xyplot $page.#auto \
313                    -layout [$itk_option(-analysis) get -object $item]]
314                pack $_widgets($item) -expand yes -fill both
315            }
316        }
317    }
318
319    # if there is only one page, take down the selector
320    if {[$itk_component(resultselector) choices size] <= 1} {
321        pack forget $itk_component(resultselector)
322    } else {
323        pack $itk_component(resultselector) -before $itk_component(results) \
324            -side top -fill x -padx {20 2}
325    }
326
327    # show the first page by default
328    set first [$itk_component(resultselector) choices get -label 0]
329    if {$first != ""} {
330        $itk_component(results) current page1
331        $itk_component(resultselector) value $first
332    }
333}
Note: See TracBrowser for help on using the repository browser.