Changeset 5029 for branches/uq/lang


Ignore:
Timestamp:
Feb 17, 2015, 5:49:36 PM (10 years ago)
Author:
mmh
Message:

puq integration snap

Location:
branches/uq/lang/tcl/scripts
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/uq/lang/tcl/scripts/library.tcl

    r4180 r5029  
    215215    public method remove {{path ""}}
    216216    public method xml {{path ""}}
     217    public method uq_make_template {}
    217218
    218219    public method diff {libobj}
     
    228229    private variable _root 0       ;# non-zero => this obj owns document
    229230    private variable _document ""  ;# XML DOM tree
    230     private variable _node ""      ;# node within 
     231    private variable _node ""      ;# node within
    231232}
    232233
     
    10381039    return $rlist
    10391040}
     1041
     1042
     1043# FIXME: get units convert. change varlist to have no units
     1044itcl::body Rappture::LibraryObj::uq_make_template {} {
     1045    set varlist ""
     1046    set n [$_node selectNodes /run/input//number]
     1047    foreach _n $n {
     1048        set x [$_n selectNodes current/text()]
     1049        set val [$x nodeValue]
     1050        if {[string equal -length 8 $val "uniform "] ||
     1051            [string equal -length 9 $val "gaussian "]} {
     1052            set unode [$_n selectNodes units/text()]
     1053            if {"" != $unode} {
     1054                set units [$unode nodeValue]
     1055                set val [Rappture::Units::mconvert $val \
     1056                -context $units -to $units -units off]
     1057            }
     1058            $x nodeValue @@[$_n getAttribute id]
     1059            lappend varlist [list [$_n getAttribute id] $val]
     1060        }
     1061    }
     1062    return $varlist
     1063}
  • branches/uq/lang/tcl/scripts/task.tcl

    r4514 r5029  
    1 # -*- mode: tcl; indent-tabs-mode: nil -*- 
     1# -*- mode: tcl; indent-tabs-mode: nil -*-
    22# ----------------------------------------------------------------------
    33#  COMPONENT: task - represents the executable part of a tool
     
    5757    # default method for -jobstats control
    5858    public proc MiddlewareTime {args}
     59
     60    public method get_params {varlist csvname uq_type args}
    5961}
    6062
     
    7577# ----------------------------------------------------------------------
    7678itcl::body Rappture::Task::constructor {xmlobj installdir args} {
     79    puts "Task Init"
    7780    if {![Rappture::library isvalid $xmlobj]} {
    7881        error "bad value \"$xmlobj\": should be Rappture::Library"
     
    138141itcl::body Rappture::Task::run {args} {
    139142    global env errorInfo
    140 
     143    puts "task run $args"
    141144    #
    142145    # Make sure that we save the proper application name.
     
    164167    foreach item {control output error} { set job($item) "" }
    165168
    166     # write out the driver.xml file for the tool
    167     set file "driver[pid].xml"
    168     set status [catch {
    169         set fid [open $file w]
    170         puts $fid "<?xml version=\"1.0\"?>"
    171         puts $fid [$_xmlobj xml]
    172         close $fid
    173     } result]
    174 
    175169    # Set limits for cpu time
    176170    set limit [$_xmlobj get tool.limits.cputime]
     
    185179            set limit 10;               # lower bound is 10 seconds.
    186180        }
    187     }
    188     Rappture::rlimit set cputime $limit 
     181    }
     182    Rappture::rlimit set cputime $limit
     183
     184    # write out the driver.xml file for the tool
     185    set file "driver[pid].xml"
     186    set status [catch {
     187        set fid [open $file w]
     188        puts $fid "<?xml version=\"1.0\"?>"
     189        puts $fid [$_xmlobj xml]
     190        close $fid
     191    } result]
     192
     193    # This will turn the driver xml into a template
     194    # and return a list of the UQ variables and their PDFs.
     195    set uq_varlist [$_xmlobj uq_make_template]
     196
     197    if {$uq_varlist != ""} {
     198        # write out the template file for submit
     199        set tfile "template[pid].xml"
     200        set status [catch {
     201            set fid [open $tfile w]
     202            puts $fid "<?xml version=\"1.0\"?>"
     203            puts $fid [$_xmlobj xml]
     204            close $fid
     205        } result]
     206    }
     207
     208
    189209    # execute the tool using the path from the tool description
    190210    if {$status == 0} {
    191211        set cmd [$_xmlobj get tool.command]
     212        puts "1. cmd=$cmd"
    192213        regsub -all @tool $cmd $_installdir cmd
    193         regsub -all @driver $cmd $file cmd
    194         regsub -all {\\} $cmd {\\\\} cmd
     214
     215        if {$uq_varlist == ""} {
     216            regsub -all @driver $cmd $file cmd
     217        } else {
     218            regsub -all @driver $cmd $tfile cmd
     219        }
    195220        set cmd [string trimleft $cmd " "]
    196         if { $cmd == "" } {
    197             puts stderr "cmd is empty"
    198             return [list 1 "Command is empty.\n\nThere is no command specified by\n\n <command>\n </command>\n\nin the tool.xml file."]
    199         }
    200 
    201         switch -glob -- [resources -jobprotocol] {
    202             "submit*" {
    203                 # if job_protocol is "submit", then use use submit command
    204                 set cmd "submit --local $cmd"
    205             }
    206             "mx" {
    207                 # metachory submission
    208                 set cmd "mx $cmd"
    209             }
    210             "exec" {
    211                 # default -- nothing special
    212             }
    213         }
     221        puts "2. cmd=$cmd"
     222        if { $cmd == "" } {
     223            puts stderr "cmd is empty"
     224            return [list 1 "Command is empty.\n\nThere is no command specified by\n\n <command>\n </command>\n\nin the tool.xml file."]
     225        }
     226
     227        if {$uq_varlist == ""} {
     228            switch -glob -- [resources -jobprotocol] {
     229                "submit*" {
     230                    # if job_protocol is "submit", then use use submit command
     231                    set cmd "submit --local $cmd"
     232                }
     233                "mx" {
     234                    # metachory submission
     235                    set cmd "mx $cmd"
     236                }
     237                "exec" {
     238                    # default -- nothing special
     239                }
     240            }
     241        } else {
     242            puts "uq_varlist=$uq_varlist"
     243            # FIXME. Default to Smolyak level 2, but allow more later.
     244            file delete -force puq
     245            set params_file [get_params $file $uq_varlist "smolyak" 2]
     246            set cmd "submit --runName=puq -l -d $params_file python uq.py $cmd @:$tfile"
     247        }
     248
    214249        $_xmlobj put tool.execute $cmd
    215250
    216         # starting job...
    217         _log run started
    218         Rappture::rusage mark
    219 
    220         if {0 == [string compare -nocase -length 5 $cmd "ECHO "] } {
    221             set status 0;
    222             set job(output) [string range $cmd 5 end]
    223         } else {
    224             set status [catch {
    225                 set ::Rappture::Task::job(control) ""
    226                 eval blt::bgexec \
    227                     ::Rappture::Task::job(control) \
    228                     -keepnewline yes \
    229                     -killsignal SIGTERM \
    230                     -onoutput [list [itcl::code $this _output]] \
     251    puts "cmd=$cmd"
     252    # starting job...
     253    _log run started
     254    Rappture::rusage mark
     255
     256    if {0 == [string compare -nocase -length 5 $cmd "ECHO "] } {
     257        set status 0;
     258        set job(output) [string range $cmd 5 end]
     259    } else {
     260        set status [catch {
     261            set ::Rappture::Task::job(control) ""
     262            eval blt::bgexec \
     263            ::Rappture::Task::job(control) \
     264            -keepnewline yes \
     265            -killsignal SIGTERM \
     266            -onoutput [list [itcl::code $this _output]] \
    231267                    -output ::Rappture::Task::job(output) \
    232268                    -error ::Rappture::Task::job(error) \
    233269                    $cmd
    234             } result]
    235 
    236             if { $status != 0 } {
    237                 # We're here because the exec-ed program failed
    238                 set logmesg $result
    239                 if { $::Rappture::Task::job(control) ne "" } {
    240                     foreach { token pid code mesg } \
    241                         $::Rappture::Task::job(control) break
    242                     if { $token == "EXITED" } {
    243                         # This means that the program exited normally but
    244                         # returned a non-zero exitcode.  Consider this an
    245                         # invalid result from the program.  Append the stderr
    246                         # from the program to the message.
    247                         set logmesg "Program finished: exit code is $code"
    248                         set result "$logmesg\n\n$::Rappture::Task::job(error)"
    249                     } elseif { $token == "abort" }  {
    250                         # The user pressed the abort button.
    251                         set logmesg "Program terminated by user."
    252                         set result "$logmesg\n\n$::Rappture::Task::job(output)"
    253                     } else {
    254                         # Abnormal termination
    255                         set logmesg "Abnormal program termination: $mesg"
    256                         set result "$logmesg\n\n$::Rappture::Task::job(output)"
    257                     }
    258                 }
    259                 _log run failed [list $logmesg]
    260                 return [list $status $result]
    261             }
    262         }
    263         # ...job is finished
    264         array set times [Rappture::rusage measure]
    265 
    266         if {[resources -jobprotocol] ne "submit"} {
    267             set id [$_xmlobj get tool.id]
    268             set vers [$_xmlobj get tool.version.application.revision]
    269             set simulation simulation
    270             if { $id ne "" && $vers ne "" } {
    271                 set pid [pid]
    272                 set simulation ${pid}_${id}_r${vers}
    273             }
    274 
    275             # need to save job info? then invoke the callback
    276             if {[string length $jobstats] > 0} {
    277                 uplevel #0 $jobstats [list job [incr jobnum] \
    278                     event $simulation start $times(start) \
    279                     walltime $times(walltime) cputime $times(cputime) \
    280                     status $status]
    281             }
    282 
    283             #
    284             # Scan through stderr channel and look for statements that
    285             # represent grid jobs that were executed.  The statements
    286             # look like this:
    287             #
    288             # MiddlewareTime: job=1 event=simulation start=3.001094 ...
    289             #
    290             set subjobs 0
    291             while {[regexp -indices {(^|\n)MiddlewareTime:( +[a-z]+=[^ \n]+)+(\n|$)} $job(error) match]} {
    292                 foreach {p0 p1} $match break
    293                 if {[string index $job(error) $p0] == "\n"} { incr p0 }
    294 
    295                 catch {unset data}
    296                 array set data {
    297                     job 1
    298                     event simulation
    299                     start 0
    300                     walltime 0
    301                     cputime 0
    302                     status 0
    303                 }
     270        } result]
     271
     272        if { $status != 0 } {
     273            # We're here because the exec-ed program failed
     274            set logmesg $result
     275            if { $::Rappture::Task::job(control) ne "" } {
     276                foreach { token pid code mesg } \
     277                $::Rappture::Task::job(control) break
     278                if { $token == "EXITED" } {
     279                   # This means that the program exited normally but
     280                   # returned a non-zero exitcode.  Consider this an
     281                   # invalid result from the program.  Append the stderr
     282                   # from the program to the message.
     283                   set logmesg "Program finished: exit code is $code"
     284                   set result "$logmesg\n\n$::Rappture::Task::job(error)"
     285                } elseif { $token == "abort" }  {
     286                    # The user pressed the abort button.
     287                    set logmesg "Program terminated by user."
     288                    set result "$logmesg\n\n$::Rappture::Task::job(output)"
     289                } else {
     290                    # Abnormal termination
     291                    set logmesg "Abnormal program termination: $mesg"
     292                    set result "$logmesg\n\n$::Rappture::Task::job(output)"
     293                }
     294            }
     295            _log run failed [list $logmesg]
     296            return [list $status $result]
     297        }
     298    }
     299    # ...job is finished
     300    array set times [Rappture::rusage measure]
     301
     302    if {[resources -jobprotocol] ne "submit"} {
     303        set id [$_xmlobj get tool.id]
     304        set vers [$_xmlobj get tool.version.application.revision]
     305        set simulation simulation
     306        if { $id ne "" && $vers ne "" } {
     307            set pid [pid]
     308            set simulation ${pid}_${id}_r${vers}
     309        }
     310
     311        # need to save job info? then invoke the callback
     312        if {[string length $jobstats] > 0} {
     313            uplevel #0 $jobstats [list job [incr jobnum] \
     314            event $simulation start $times(start) \
     315            walltime $times(walltime) cputime $times(cputime) \
     316            status $status]
     317        }
     318
     319        #
     320        # Scan through stderr channel and look for statements that
     321        # represent grid jobs that were executed.  The statements
     322        # look like this:
     323        #
     324        # MiddlewareTime: job=1 event=simulation start=3.001094 ...
     325        #
     326        set subjobs 0
     327        while {[regexp -indices {(^|\n)MiddlewareTime:( +[a-z]+=[^ \n]+)+(\n|$)} $job(error) match]} {
     328            foreach {p0 p1} $match break
     329            if {[string index $job(error) $p0] == "\n"} { incr p0 }
     330
     331            catch {unset data}
     332            array set data {
     333                job 1
     334                event simulation
     335                start 0
     336                walltime 0
     337                cputime 0
     338                status 0
     339            }
    304340                foreach arg [lrange [string range $job(error) $p0 $p1] 1 end] {
    305341                    foreach {key val} [split $arg =] break
     
    337373    }
    338374    if {$status == 0} {
    339         file delete -force -- $file
     375        # file delete -force -- $file
    340376    }
    341377
     
    350386    # a reference to the run.xml file containing results.
    351387    #
     388
    352389    if {$status == 0} {
    353390        set result [string trim $job(output)]
     391        puts "result=$result"
     392        if {$uq_varlist != ""} {
     393            file delete -force -- new.xml
     394            exec puq_analyze.py puq_[pid].hdf5
     395            append result "\n" "=RAPPTURE-RUN=>new.xml"
     396        }
    354397        if {[regexp {=RAPPTURE-RUN=>([^\n]+)} $result match file]} {
    355398            set status [catch {Rappture::library $file} result]
     399            puts "STATUS=$status"
    356400            if {$status == 0} {
    357401                # add cputime info to run.xml file
     
    381425            if {$status == 0 && $rdir ne ""} {
    382426                catch {
    383                     file delete -force -- $file
     427                    # file delete -force -- $file
    384428                    if {![file exists $rdir]} {
    385429                        _mkdir $rdir
     
    393437            } else {
    394438                # don't keep the file
    395                 file delete -force -- $file
     439                # file delete -force -- $file
    396440            }
    397441        } else {
     
    518562    puts stderr $line
    519563}
     564
     565
     566#
     567# Send the list of parameters to a python program so it can call PUQ
     568# and get a CSV file containing the parameter values to use for the runs.
     569itcl::body Rappture::Task::get_params {dfile varlist uq_type args} {
     570
     571    # convert tcl list of variables to json so python can read it
     572    proc varlist2py {inlist} {
     573        set ovar "\["
     574        set first 1
     575        foreach a $inlist {
     576            foreach {var val} $a break
     577            if {$first == 1} {
     578                append ovar \[\"$var\",
     579                set first 0
     580            } else {
     581                append ovar \],\[\"$var\",
     582            }
     583            switch [lindex $val 0] {
     584                gaussian {
     585                    append ovar "\[\"gaussian\",[lindex $val 1],[lindex $val 2]\]"
     586                }
     587                uniform {
     588                    append ovar "\[\"uniform\",[lindex $val 1],[lindex $val 2]\]"
     589                }
     590                default {
     591                    append ovar $val
     592                }
     593            }
     594        }
     595        append ovar "\]\]"
     596        return $ovar
     597    }
     598
     599    puts "varlist=$varlist"
     600    set varlist [varlist2py $varlist]
     601    set pid [pid]
     602    exec get_params.py $dfile $pid $varlist $uq_type $args
     603    return params[pid].csv
     604}
  • branches/uq/lang/tcl/scripts/units.tcl

    r3362 r5029  
     1# -*- mode: tcl; indent-tabs-mode: nil -*-
    12# ----------------------------------------------------------------------
    23#  COMPONENT: units - mechanism for converting numbers with units
     
    6061}
    6162
     63
     64# ----------------------------------------------------------------------
     65# USAGE: mcheck_range value {min ""} {max ""}
     66#
     67# Checks a value or PDF to determine if is is in a required range.
     68# Automatically does unit conversion if necessary.
     69# Returns value if OK.  Error if out-of-range
     70# Examples:
     71#    [mcheck_range "gaussian 0C 1C" 200K 500K] returns 1
     72#    [mcheck_range "uniform 100 200" 150 250] returns 0
     73#    [mcheck_range 100 0 200] returns 1
     74# ----------------------------------------------------------------------
     75
     76proc Rappture::Units::_check_range {value min max units} {
     77    # make sure the value has units
     78    if {$units != ""} {
     79        set value [Rappture::Units::convert $value -context $units]
     80        # for comparisons, remove units
     81        set nv [Rappture::Units::convert $value -units off]
     82        # get the units for the value
     83        set newunits [Rappture::Units::Search::for $value]
     84    } else {
     85        set nv $value
     86    }
     87
     88    if {"" != $min} {
     89        if {"" != $units} {
     90            # compute the minimum in the new units
     91            set minv [Rappture::Units::convert $min -to $newunits -units off]
     92            # same, but include units for printing
     93            set convMinVal [Rappture::Units::convert $min -to $newunits]
     94        } else {
     95            set minv $min
     96            set convMinVal $min
     97        }
     98        if {$nv < $minv} {
     99            error "Minimum value allowed here is $convMinVal"
     100        }
     101    }
     102    if {"" != $max} {
     103        if {"" != $units} {
     104            # compute the maximum in the new units
     105            set maxv [Rappture::Units::convert $max -to $newunits -units off]
     106            # same, but include units for printing
     107            set convMaxVal [Rappture::Units::convert $max -to $newunits]
     108        } else {
     109            set maxv $max
     110            set convMaxVal $max
     111        }
     112        if {$nv > $maxv} {
     113            error "Maximum value allowed here is $convMaxVal"
     114        }
     115    }
     116    return $value
     117}
     118
     119proc Rappture::Units::mcheck_range {value {min ""} {max ""} {units ""}} {
     120    puts "mcheck_range $value min=$min max=$max units=$units"
     121
     122    switch -- [lindex $value 0] {
     123        normal -
     124        gaussian {
     125            # get the mean
     126            set mean [_check_range [lindex $value 1] $min $max $units]
     127            if {$units == ""} {
     128                set dev [lindex $value 2]
     129                set ndev $dev
     130            } else {
     131                set dev [Rappture::Units::convert [lindex $value 2] -context $units]
     132                set ndev [Rappture::Units::convert $dev -units off]
     133            }
     134            if {$ndev <= 0} {
     135                error "Deviation must be positive."
     136            }
     137            return [list gaussian $mean $dev]
     138        }
     139        uniform {
     140            set min [_check_range [lindex $value 1] $min $max $units]
     141            set max [_check_range [lindex $value 2] $min $max $units]
     142            return [list uniform $min $max]
     143        }
     144        exact  {
     145            return [_check_range [lindex $value 1] $min $max $units]
     146        }
     147        default {
     148            return [_check_range [lindex $value 0] $min $max $units]
     149        }
     150    }
     151}
     152
     153# ----------------------------------------------------------------------
     154# USAGE: mconvert value ?-context units? ?-to units? ?-units on/off?
     155#
     156# This version of convert() converts multiple values.  Used when the
     157# value could be a range or probability density function (PDF).
     158# Examples:
     159#    gaussian 100k 1k
     160#    uniform 0eV 10eV
     161#    42
     162#    exact 42
     163# ----------------------------------------------------------------------
     164
     165proc Rappture::Units::mconvert {value args} {
     166    puts "mconvert $value : $args"
     167    array set opts {
     168        -context ""
     169        -to ""
     170        -units "on"
     171    }
     172
     173    set value [split $value]
     174
     175    switch [lindex $value 0] {
     176        normal -
     177        gaussian {
     178            set valtype gaussian
     179            set vals [lrange $value 1 2]
     180            set convtype {0 1}
     181        }
     182        uniform {
     183            set valtype uniform
     184            set vals [lrange $value 1 2]
     185            set convtype {0 0}
     186        }
     187        exact  {
     188            set valtype ""
     189            set vals [lindex $value 1]
     190            set convtype {0}
     191        }
     192        default {
     193            set valtype ""
     194            set vals $value
     195            set convtype {0}
     196        }
     197    }
     198
     199    foreach {key val} $args {
     200        if {![info exists opts($key)]} {
     201            error "bad option \"$key\": should be [join [lsort [array names opts]] {, }]"
     202        }
     203        set opts($key) $val
     204    }
     205
     206    set newval $valtype
     207    foreach val $vals ctype $convtype {
     208        if {$ctype == 1} {
     209            # This code handles unit conversion for deltas (changes).
     210            # For example, if we want a standard deviation of 10C converted
     211            # to Kelvin, that is 10K, NOT a standard deviation of 283.15K.
     212            set units [Rappture::Units::Search::for $val]
     213            set base [eval Rappture::Units::convert 0$units $args -units off]
     214            set new [eval Rappture::Units::convert $val $args -units off]
     215            set delta [expr $new - $base]
     216            set val $delta$opts(-to)
     217        }
     218        # tcl 8.5 allows us to do this:
     219        # lappend newval [Rappture::Units::convert $val {*}$args]
     220        # but we are using tcl8.4 so we use eval :^(
     221        lappend newval [eval Rappture::Units::convert $val $args]
     222    }
     223    return $newval
     224}
     225
    62226# ----------------------------------------------------------------------
    63227# USAGE: convert value ?-context units? ?-to units? ?-units on/off?
     
    69233# current system.
    70234# ----------------------------------------------------------------------
    71 proc Rappture::Units::convert {value args} {
    72     array set opts {
    73         -context ""
    74         -to ""
    75         -units "on"
    76     }
    77     foreach {key val} $args {
    78         if {![info exists opts($key)]} {
    79             error "bad option \"$key\": should be [join [lsort [array names opts]] {, }]"
    80         }
    81         set opts($key) $val
    82     }
    83 
    84     #
    85     # Parse the value into the number part and the units part.
    86     #
    87     set value [string trim $value]
    88     if {![regexp {^([-+]?[0-9]+\.?([0-9]+)?([eEdD][-+]?[0-9]+)?) *(/?[a-zA-Z]+[0-9]*)?$} $value match number dummy1 dummy2 units]} {
    89         set mesg "bad value \"$value\": should be real number with units"
    90         if {$opts(-context) != ""} {
    91             append mesg " of [Rappture::Units::description $opts(-context)]"
    92         }
    93         error $mesg
    94     }
    95     if {$units == ""} {
    96         set units $opts(-context)
    97     }
    98 
    99     #
    100     # Try to find the object representing the current system of units.
    101     #
    102     set units [Rappture::Units::System::regularize $units]
    103     set oldsys [Rappture::Units::System::for $units]
    104     if {$oldsys == ""} {
    105         set mesg "value \"$value\" has unrecognized units"
    106         if {$opts(-context) != ""} {
    107             append mesg ".\nShould be units of [Rappture::Units::description $opts(-context)]"
    108         }
    109         error $mesg
    110     }
    111 
    112     #
    113     # Convert the number to the new system of units.
    114     #
    115     if {$opts(-to) == ""} {
    116         # no units -- return the number as is
    117         return "$number$units"
    118     }
    119     return [$oldsys convert "$number$units" $opts(-to) $opts(-units)]
    120 }
     235# proc Rappture::Units::convert {value args} {}
     236# Actual implementation is in rappture/lang/tcl/src/RpUnitsTclInterface.cc.
     237
    121238
    122239# ----------------------------------------------------------------------
     
    127244# along with a list of all compatible systems.
    128245# ----------------------------------------------------------------------
    129 proc Rappture::Units::description {units} {
    130     set sys [Rappture::Units::System::for $units]
    131     if {$sys == ""} {
    132         return ""
    133     }
    134     set mesg [$sys cget -type]
    135     set ulist [Rappture::Units::System::all $units]
    136     if {"" != $ulist} {
    137         append mesg " ([join $ulist {, }])"
    138     }
    139     return $mesg
    140 }
     246# proc Rappture::Units::description {units} {}
     247# Actual implementation is in rappture/lang/tcl/src/RpUnitsTclInterface.cc.
     248
    141249
    142250# ----------------------------------------------------------------------
     
    153261    private variable _system ""  ;# this system of units
    154262
    155     public proc for {units}
    156     public proc all {units}
     263    # These are in rappture/lang/tcl/src/RpUnitsTclInterface.cc.
     264    # public proc for {units}
     265    # public proc all {units}
     266
    157267    public proc regularize {units}
    158268
     
    360470# if there is no system that matches the units string.
    361471# ----------------------------------------------------------------------
    362 itcl::body Rappture::Units::System::for {units} {
    363     #
    364     # See if the units are a recognized system.  If not, then try to
    365     # extract any metric prefix and see if what's left is a recognized
    366     # system.  If all else fails, see if we can find a system without
    367     # the exact capitalization.  The user might say "25c" instead of
    368     # "25C".  Try to allow that.
    369     #
    370     if {[info exists _base($units)]} {
    371         return $_base($units)
    372     } else {
    373         set orig $units
    374         if {[regexp {^(/?)[cCmMuUnNpPfFaAkKgGtT](.+)$} $units match slash tail]} {
    375             set base "$slash$tail"
    376             if {[info exists _base($base)]} {
    377                 set sys $_base($base)
    378                 if {[$sys cget -metric]} {
    379                     return $sys
    380                 }
    381             }
    382 
    383             # check the base part for improper capitalization below...
    384             set units $base
    385         }
    386 
    387         set matching ""
    388         foreach u [array names _base] {
    389             if {[string equal -nocase $u $units]} {
    390                 lappend matching $_base($u)
    391             }
    392         }
    393         if {[llength $matching] == 1} {
    394             set sys [lindex $matching 0]
    395             #
    396             # If we got rid of a metric prefix above, make sure
    397             # that the system is metric.  If not, then we don't
    398             # have a match.
    399             #
    400             if {[string equal $units $orig] || [$sys cget -metric]} {
    401                 return $sys
    402             }
    403         }
    404     }
    405     return ""
    406 }
     472# itcl::body Rappture::Units::System::for {units} {}
     473# Actual implementation is in rappture/lang/tcl/src/RpUnitsTclInterface.cc.
     474
    407475
    408476# ----------------------------------------------------------------------
     
    413481# relationships that lead to the same base system.
    414482# ----------------------------------------------------------------------
    415 itcl::body Rappture::Units::System::all {units} {
    416     set sys [Rappture::Units::System::for $units]
    417     if {$sys == ""} {
    418         return ""
    419     }
    420 
    421     if {"" != [$sys cget -basis]} {
    422         set basis [lindex [$sys cget -basis] 0]
    423     } else {
    424         set basis $units
    425     }
    426 
    427     set ulist $basis
    428     foreach u [array names _base] {
    429         set obj $_base($u)
    430         set b [lindex [$obj cget -basis] 0]
    431         if {$b == $basis} {
    432             lappend ulist $u
    433         }
    434     }
    435     return $ulist
    436 }
     483# itcl::body Rappture::Units::System::all {units} {}
     484# Actual implementation is in rappture/lang/tcl/src/RpUnitsTclInterface.cc.
     485
    437486
    438487# ----------------------------------------------------------------------
Note: See TracChangeset for help on using the changeset viewer.