source: trunk/gui/scripts/sequence.tcl @ 1536

Last change on this file since 1536 was 1342, checked in by gah, 15 years ago

preliminary HQ output from molvisviewer; unexpand tabs; all jpeg generation at 100%

File size: 7.4 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: sequence - represents a sequence of output results
3#
4#  This object represents a sequence of other output results.  Each
5#  element in the sequence has an index and a value.  All values in
6#  the sequence must have the same type, but they can all be curves,
7#  images, or other results.
8# ======================================================================
9#  AUTHOR:  Michael McLennan, Purdue University
10#  Copyright (c) 2004-2005  Purdue Research Foundation
11#
12#  See the file "license.terms" for information on usage and
13#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14# ======================================================================
15package require Itcl
16package require BLT
17
18namespace eval Rappture { # forward declaration }
19
20itcl::class Rappture::Sequence {
21    constructor {xmlobj path} { # defined below }
22    destructor { # defined below }
23
24    public method value {pos}
25    public method label {pos}
26    public method index {pos}
27    public method size {}
28    public method hints {{keyword ""}}
29
30    private variable _xmlobj ""  ;# ref to lib obj with sequence data
31    private variable _dataobjs   ;# maps index => data object
32    private variable _labels     ;# maps index => labels
33    private variable _indices    ;# list of sorted index values
34    private variable _hints      ;# cache of hints stored in XML
35}
36
37# ----------------------------------------------------------------------
38# CONSTRUCTOR
39# ----------------------------------------------------------------------
40itcl::body Rappture::Sequence::constructor {xmlobj path} {
41    if {![Rappture::library isvalid $xmlobj]} {
42        error "bad value \"$xmlobj\": should be LibraryObj"
43    }
44    set _xmlobj [$xmlobj element -as object $path]
45
46    #
47    # Extract data values from the element definitions.
48    #
49    foreach name [$_xmlobj children -type element] {
50        set index [$xmlobj get $path.$name.index]
51        if {"" == $index} {
52            continue
53        }
54
55        # check for an element about.label stanza
56        set elelabel [$xmlobj get $path.$name.about.label]
57
58        set ctype ""
59        set _dataobjs($index) ""
60        set _labels($index) ""
61        foreach cname [$_xmlobj children $name] {
62            set type [$xmlobj element -as type $path.$name.$cname]
63            switch -- $type {
64                index {
65                    # ignore this
66                    continue
67                }
68                about {
69                    # ignore this
70                    continue
71                }
72                curve {
73                    set obj [Rappture::Curve ::#auto $xmlobj $path.$name.$cname]
74                }
75                histogram {
76                    set obj [Rappture::Histogram ::#auto $xmlobj $path.$name.$cname]
77                }
78                field {
79                    set obj [Rappture::Field ::#auto $xmlobj $path.$name.$cname]
80                }
81                image {
82                    set obj [Rappture::Image ::#auto $xmlobj $path.$name.$cname]
83                }
84                structure {
85                    # extract unique result set prefix
86                    scan $xmlobj "::libraryObj%d" rset
87
88                    # object rooted at x.sequence(y).element(z).structure
89                    set obj [$xmlobj element -as object $path.$name.$cname]
90
91                    # scene id (sequence id)
92                    set sceneid [$xmlobj element -as id $path]-$rset
93
94                    # sequence/element/frame number starting at 1
95                    set frameid [expr [$xmlobj element -as id $path.$name] + 1]
96
97                    # only supporting one molecule per structure at the moment
98                    # otherwise should go through all children that are molecules
99                    # and insert scene/frame data.
100                    $obj put "components.molecule.state" $frameid
101                    $obj put "components.molecule.model" $sceneid
102                }
103                default {
104                    error "don't know how to handle sequences of $type"
105                }
106            }
107            if {"" == $ctype} {
108                set ctype $type
109            }
110            if {$type == $ctype} {
111                lappend _dataobjs($index) $obj
112                set _labels($index) $elelabel
113            } else {
114                itcl::delete object $obj
115            }
116        }
117    }
118
119    #
120    # Generate a list of sorted index values.
121    #
122    set units [$xmlobj get $path.index.units]
123    if {"" != $units} {
124        # build up a list:  {10m 10} {10cm 0.1} ...
125        set vals ""
126        foreach key [array names _dataobjs] {
127            lappend vals [list $key [Rappture::Units::convert $key \
128                -context $units -to $units -units off]]
129        }
130
131        # sort according to raw values; store both values
132        set _indices [lsort -real -index 1 $vals]
133
134    } else {
135        # are the indices integers, reals, or strings?
136        set how -integer
137        foreach key [array names _dataobjs] {
138            if {[regexp {^[0-9]+[eE][-+]?[0-9]+|([0-9]+)?\.[0-9]+([eE][-+]?[0-9]+)?$} $key]} {
139                set how -real
140                break
141            } elseif {![regexp {^[0-9]+$} $key]} {
142                set how -dictionary
143                break
144            }
145        }
146
147        # keep a list of indices sorted in order
148        set _indices ""
149        if {[string equal $how -dictionary]} {
150            set n 0
151            foreach val [lsort $how [array names _dataobjs]] {
152                lappend _indices [list $val $n]
153                incr n
154            }
155        } else {
156            foreach val [lsort $how [array names _dataobjs]] {
157                lappend _indices [list $val $val]
158            }
159        }
160    }
161}
162
163# ----------------------------------------------------------------------
164# DESTRUCTOR
165# ----------------------------------------------------------------------
166itcl::body Rappture::Sequence::destructor {} {
167    foreach key [array names _dataobjs] {
168        eval itcl::delete object $_dataobjs($key)
169    }
170    itcl::delete object $_xmlobj
171}
172
173# ----------------------------------------------------------------------
174# USAGE: value <pos>
175#
176# Returns the value for the element as position <pos> in the
177# list of all elements.  Here, <pos> runs from 0 to size-1.
178# ----------------------------------------------------------------------
179itcl::body Rappture::Sequence::value {pos} {
180    set i [lindex [lindex $_indices $pos] 0]
181    return $_dataobjs($i)
182}
183
184# ----------------------------------------------------------------------
185# USAGE: label <pos>
186#
187# Returns the label for the element as position <pos> in the
188# list of all elements.  Here, <pos> runs from 0 to size-1.
189# ----------------------------------------------------------------------
190itcl::body Rappture::Sequence::label {pos} {
191    set i [lindex [lindex $_indices $pos] 0]
192    return $_labels($i)
193}
194
195# ----------------------------------------------------------------------
196# USAGE: index <pos>
197#
198# Returns information about the index value for the element at
199# position <pos> in the list of all elements.  The return value is
200# a list of two elements:  {string rawNumberValue}.  Here, <pos>
201# runs from 0 to size-1.
202# ----------------------------------------------------------------------
203itcl::body Rappture::Sequence::index {pos} {
204    return [lindex $_indices $pos]
205}
206
207# ----------------------------------------------------------------------
208# USAGE: size
209#
210# Returns the number of elements in this sequence.
211# ----------------------------------------------------------------------
212itcl::body Rappture::Sequence::size {} {
213    return [llength $_indices]
214}
215
216# ----------------------------------------------------------------------
217# USAGE: hints ?<keyword>?
218#
219# Returns a list of key/value pairs for various hints about showing
220# this image.  If a particular <keyword> is specified, then it returns
221# the hint for that <keyword>, if it exists.
222# ----------------------------------------------------------------------
223itcl::body Rappture::Sequence::hints {{keyword ""}} {
224    if {![info exists _hints]} {
225        foreach {key path} {
226            label        about.label
227            indexlabel   index.label
228            indexdesc    index.description
229        } {
230            set str [$_xmlobj get $path]
231            if {"" != $str} {
232                set _hints($key) $str
233            }
234        }
235    }
236
237    if {$keyword != ""} {
238        if {[info exists _hints($keyword)]} {
239            return $_hints($keyword)
240        }
241        return ""
242    }
243    return [array get _hints]
244}
Note: See TracBrowser for help on using the repository browser.