source: trunk/gui/scripts/curve.tcl @ 11

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

Major reorganization of the entire package. The config.xml file
is now irrelevant. All the action is in the tool.xml file. The
main program now organizes all input into 1) side-by-side pages,
2) input/result (wizard-style) pages, or 3) a series of wizard-
style pages. The <input> can have <phase> parts representing
the various pages.

Added a new ContourResult? widget based on Swaroop's vtk plotting
code.

Also, added easymesh and showmesh to the "tools" directory.
We need these for Eric Polizzi's code.

File size: 7.5 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: curve - extracts data from an XML description of a field
3#
4#  This object represents a curve of data in an XML description of
5#  simulator output.  A curve is similar to a field, but a field is
6#  a quantity versus position in device.  A curve is any quantity
7#  versus any other quantity.  This class simplifies the process of
8#  extracting data vectors that represent the curve.
9# ======================================================================
10#  AUTHOR:  Michael McLennan, Purdue University
11#  Copyright (c) 2004-2005
12#  Purdue Research Foundation, West Lafayette, IN
13# ======================================================================
14package require Itcl
15package require BLT
16
17namespace eval Rappture { # forward declaration }
18
19itcl::class Rappture::Curve {
20    constructor {xmlobj path} { # defined below }
21    destructor { # defined below }
22
23    public method components {{pattern *}}
24    public method mesh {{what -overall}}
25    public method values {{what -overall}}
26    public method limits {which}
27    public method hints {{key ""}}
28
29    protected method _build {}
30
31    private variable _xmlobj ""  ;# ref to lib obj with curve data
32    private variable _curve ""   ;# lib obj representing this curve
33    private variable _comp2xy    ;# maps component name => x,y vectors
34
35    private common _counter 0    ;# counter for unique vector names
36}
37
38# ----------------------------------------------------------------------
39# CONSTRUCTOR
40# ----------------------------------------------------------------------
41itcl::body Rappture::Curve::constructor {xmlobj path} {
42    if {![Rappture::library isvalid $xmlobj]} {
43        error "bad value \"$xmlobj\": should be LibraryObj"
44    }
45    set _xmlobj $xmlobj
46    set _curve [$xmlobj element -as object $path]
47
48    # build up vectors for various components of the curve
49    _build
50}
51
52# ----------------------------------------------------------------------
53# DESTRUCTOR
54# ----------------------------------------------------------------------
55itcl::body Rappture::Curve::destructor {} {
56    itcl::delete object $_curve
57    # don't destroy the _xmlobj! we don't own it!
58
59    foreach name [array names _comp2xy] {
60        eval blt::vector destroy $_comp2xy($name)
61    }
62}
63
64# ----------------------------------------------------------------------
65# USAGE: components ?<pattern>?
66#
67# Returns a list of names for the various components of this curve.
68# If the optional glob-style <pattern> is specified, then it returns
69# only the component names matching the pattern.
70# ----------------------------------------------------------------------
71itcl::body Rappture::Curve::components {{pattern *}} {
72    set rlist ""
73    foreach name [array names _comp2xy] {
74        if {[string match $pattern $name]} {
75            lappend rlist $name
76        }
77    }
78    return $rlist
79}
80
81# ----------------------------------------------------------------------
82# USAGE: mesh ?<name>?
83#
84# Returns the xvec for the specified curve component <name>.
85# If the name is not specified, then it returns the vectors for the
86# overall curve (sum of all components).
87# ----------------------------------------------------------------------
88itcl::body Rappture::Curve::mesh {{what -overall}} {
89    if {[info exists _comp2xy($what)]} {
90        return [lindex $_comp2xy($what) 0]  ;# return xv
91    }
92    error "bad option \"$what\": should be [join [lsort [array names _comp2xy]] {, }]"
93}
94
95# ----------------------------------------------------------------------
96# USAGE: values ?<name>?
97#
98# Returns the xvec for the specified curve component <name>.
99# If the name is not specified, then it returns the vectors for the
100# overall curve (sum of all components).
101# ----------------------------------------------------------------------
102itcl::body Rappture::Curve::values {{what -overall}} {
103    if {[info exists _comp2xy($what)]} {
104        return [lindex $_comp2xy($what) 1]  ;# return yv
105    }
106    error "bad option \"$what\": should be [join [lsort [array names _comp2xy]] {, }]"
107}
108
109# ----------------------------------------------------------------------
110# USAGE: limits x|y
111#
112# Returns the {min max} limits for the specified axis.
113# ----------------------------------------------------------------------
114itcl::body Rappture::Curve::limits {which} {
115    set min ""
116    set max ""
117    switch -- $which {
118        x { set pos 0 }
119        y { set pos 1 }
120        default {
121            error "bad option \"$which\": should be x or y"
122        }
123    }
124    foreach comp [array names _comp2xy] {
125        set vname [lindex $_comp2xy($comp) $pos]
126        $vname variable vec
127        if {"" == $min} {
128            set min $vec(min)
129        } elseif {$vec(min) < $min} {
130            set min $vec(min)
131        }
132        if {"" == $max} {
133            set max $vec(max)
134        } elseif {$vec(max) > $max} {
135            set max $vec(max)
136        }
137    }
138    return [list $min $max]
139}
140
141# ----------------------------------------------------------------------
142# USAGE: hints ?<keyword>?
143#
144# Returns a list of key/value pairs for various hints about plotting
145# this curve.  If a particular <keyword> is specified, then it returns
146# the hint for that <keyword>, if it exists.
147# ----------------------------------------------------------------------
148itcl::body Rappture::Curve::hints {{keyword ""}} {
149    foreach {key path} {
150        label   label
151        color   color
152        color   style
153        xlabel  xaxis.label
154        xunits  xaxis.units
155        xscale  xaxis.scale
156        ylabel  yaxis.label
157        yunits  yaxis.units
158        yscale  yaxis.scale
159    } {
160        set str [$_curve get $path]
161        if {"" != $str} {
162            set hints($key) $str
163        }
164    }
165
166    if {[info exists hints(xlabel)] && "" != $hints(xlabel)
167          && [info exists hints(xunits)] && "" != $hints(xunits)} {
168        set hints(xlabel) "$hints(xlabel) ($hints(xunits))"
169    }
170    if {[info exists hints(ylabel)] && "" != $hints(ylabel)
171          && [info exists hints(yunits)] && "" != $hints(yunits)} {
172        set hints(ylabel) "$hints(ylabel) ($hints(yunits))"
173    }
174
175    if {$keyword != ""} {
176        if {[info exists hints($keyword)]} {
177            return $hints($keyword)
178        }
179        return ""
180    }
181    return [array get hints]
182}
183
184# ----------------------------------------------------------------------
185# USAGE: _build
186#
187# Used internally to build up the vector representation for the
188# curve when the object is first constructed, or whenever the curve
189# data changes.  Discards any existing vectors and builds everything
190# from scratch.
191# ----------------------------------------------------------------------
192itcl::body Rappture::Curve::_build {} {
193    # discard any existing data
194    foreach name [array names _comp2xy] {
195        eval blt::vector destroy $_comp2xy($name)
196    }
197    catch {unset _comp2xy}
198
199    #
200    # Scan through the components of the curve and create
201    # vectors for each part.
202    #
203    foreach cname [$_curve children -type component] {
204        set xv ""
205        set yv ""
206
207        set xydata [$_curve get $cname.xy]
208        if {"" != $xydata} {
209            set xv [blt::vector create x$_counter]
210            set yv [blt::vector create y$_counter]
211
212            foreach line [split $xydata \n] {
213                if {[scan $line {%g %g} xval yval] == 2} {
214                    $xv append $xval
215                    $yv append $yval
216                }
217            }
218        }
219
220        if {$xv != "" && $yv != ""} {
221            set _comp2xy($cname) [list $xv $yv]
222            incr _counter
223        }
224    }
225}
Note: See TracBrowser for help on using the repository browser.