3# the next line restarts using wish \
4exec /bin/nice bltwish "$0" -- ${1+"$@"}
6#=========================================================================
7# Gertjan Hofman, U. of Colorado, Boulder, March-00.
9# tcl program to replace the gstripchart thingy that comes with
13# requires: tcl + tk + BLT = bltwish
15# v 1.0 Mar - 00 for PAA/Triumf/Midas
17# There are a few tricky things going on here.
18# Since passing TCL lists to the graph seems to have a memory leak,
19# I use BLT vectors, which are hot linked to the graph elements.
20# Since I dont know a priori how many vectors to create, I the name
21# of the item that I am plotting as the vector name, preceded by
23# To access an individual data point, which I need for the scrolling
24# now have to do a double de-refencing. Say we create a vector
25# vector create my_vect(10)
26# then I can access the vector using puts $my_vect(3)
30# Now I need to translate x--> my_vect --> its value.
31# you can do this in two ways:
32# puts [set [set x](0)] or puts [ set ${x}(0)] or even
33# puts [set $x\(0)]. In the first case, the inner 'set' returns
34# my_vect. This is then appended to (0) and the second set returns
35# the result. In the last case, the \ 'escapes' or seperates the (0)
36# as not being part of the name. etc etc. Think about it.
38# v. 1.0 -added help menu, added smarter scaling of of the expanded
40# v 1.1 -added mouse select of graph items
41# v. 2.0 -added support for mhist (odb history)
42# v. 2.1 -added postscript support + zooming of single graph windows
43# v 3.0 -added scroll bars for variable selections
44# -corrected dd.mm.yy to yy.mm.dd for Stefan.
46# - improve help/info menu's
48# - check compatibility with gchart, esp. reading of fields
49# - what about simple arithmetic ? (a la gchart).
50# - think of some cool back grounds (chaos.../midas etc)
54# 1. Search for most recent mhist executable and use that
55# 2. Change history file menu's slightly
56# 3. option -mhist is no longer necessary - default
59# fixed bug in online mode - string comparison was wrong
60# re-ordered some code (no functional change)
66# Updates - discovered minor bugs in decoding time format for the year 2001
67# - minor bug in exec statements (was appending new items instead
69# -* found BLT problesm - things that worked before dont with
70# RH72 distr - nameles vector x(++end) $data kind of statements
71# Had to use vector append instead.
74# Added file path input box.
75# Added busy signal - changing colour of the screen
78# Added buttons to scan through the expanded/single graphs
79# Allow resizing of expanded/single graphs
81# May-2002. Cosmetic changes.
82# Allow Manual entry of y-scale settings
84#========================================================================
87namespace import blt::* ;# get BLT commands imported
89#============================================================
90# SHOW MESSAGE - pop up message window and display error
91#============================================================
93proc show_message {message} {
94 global message_done ;# indicate whether message has been read
95 toplevel .messages ; # create a new window
96 wm title .messages "stripchart warning"
97 label .messages.1 -text "$message"
98 pack .messages.1 -side top
99 button .messages.ok -text "OK" -command {
103 pack .messages.ok -side bottom
108#=============================================================
109# Convert clock seconds to HH:MM:SS format
110#=============================================================
111# this function converts a 'x' axis value to a time format according to
112# a format statement passed to it.
113proc my_clock_format {format graph ltime} {
114 return "[clock format [expr round( ($ltime/60.)*60)] -format $format]"
118#=============================================================
120#=============================================================
125#=============================================================
126# FIND LATEST MHIST VERSION -by checking modificationd dates
127#=============================================================
128proc find_newest_mhist {} {
132 # search for the latest copy of mhist and store that path
133 set mhistlist "/usr/local/bin /usr/bin . /midas/linux/bin/"
135 foreach file $mhistlist {
136 # get the modification time
137 if [file exist $file/mhist] {
138 if {[file mtime $file/mhist] > $minmod } {
139 set minmod [file mtime $file/mhist]
145 if {$mhist_path==""} {
146 tk_messageBox -message "Error: Can not find ANY mhist in \n
150 wm title . "using mhist from path: $mhist_path/mhist"
156#==============================================================
157# READ THE MCHART CONFIGURATION FILE
158#==============================================================
159proc read_conf_file {conf_fname} {
161 global item_fname item_fields item_pattern item_equation
162 global item_color item_max item_min item_list
165 # open the file, get ptr.
166 set file_hndl [open $conf_fname r]
168 while {! [eof $file_hndl]} {
170 gets $file_hndl string
172 # skip over comments ...except catch Pierre's equipment name.
173 if {[string first "#Equipment:" $string] != -1 } {
174 set equip_name [lindex $string 1]
177 if {[string index $string 0]=="#" || [llength $string]==0} {
180 set string [string tolower $string] ;# convert to lower case
182 #disect string to obtain info. Look for begin line.
183 # note: string first return location of first occurance -1 if not found
184 if { [string first "begin:" $string] != -1} {
186 # now fetch the second item - the value name
188 set item [lindex $string 1] ;# assume its the second item
190 set item [filter_bad_chars $item]
192 lappend item_list $item ;# create a list of items for looping
194 set item_color($item) [get_new_color]
195 # "color:" { set item_color($item) [lindex $string 1] }
196 # ok we got a begin. Check for the usefil items
197 while { [string first "end:" $string] == -1 } {
198 gets $file_hndl string
199 switch -glob -- [lindex $string 0] {
200 "filename:" { set item_fname($item) [lindex $string 1] }
201 "fields:" { set item_fields($item) [lindex $string 1] }
202 "pattern:" { set item_pattern($item) [lindex $string 1] }
203 "equation:" { set item_equation($item) [lindex $string 1] }
204 "maximum:" { set item_max($item) [lindex $string 1] }
205 "minimum:" { set item_min($item) [lindex $string 1] }
207 show_message "Error in .conf file - begin but no previous end "
219# do some checks on the max/min values, in case Pierre screwed them up
220 foreach item $item_list {
221 if { $item_max($item)==0 && $item_min($item)==0} {
222 puts "found zero max/min values for $item. Correcting"
223 set item_max($item) 1
232#======================================================================
233# GRAPH INDIVIDUAL ITEM ON FULL SCALE
234#======================================================================
236proc select_graph {item} {
237# here we show the REAL data, unscaled, on a seperate graph
238# note: we want to be able to crack open multiple graphs
239# so the names of the widget need to be a variable.
240# can't remember how to make static variables, so make it
243# global V_x_$item ;# vectors associated with the plotte item
245 global item_color ;# colour associated with item
246 global scale_ymin scale_ymax ;# present best y-scale
247 global winsize_x winsize_y ;# size of toplevel and graph windows
250# check if window exist already - dont replot the same item twice
251 if [winfo exists .fullscale$item ] {
252 wm deiconify .fullscale$item ;# de-iconize it it
253 raise .fullscale$item ;# raise to foreground
257 toplevel .fullscale$item ;# create new window with unique name
258 wm title .fullscale$item "$item"
260# split screen in two parts -
261 frame .fullscale$item.col1 ;# create to columes - rhs for graph
262 frame .fullscale$item.col2 ;# left hand side for buttons.
263 pack .fullscale$item.col1 -side left
264 pack .fullscale$item.col2 -side right -fill both -expand 1
266 set fgraph .fullscale$item.col2.graph
268 graph $fgraph -title "" -relief ridge -bd 3 -background "#c8f8ce" ;# make a new graph
269 #cross hairs - why doesnt $fgraph crosshair on work ?
270 Blt_Crosshairs $fgraph
271 $fgraph configure -width 5.0i -height 2.0i ;# configure it a little
272 $fgraph legend configure -position @80,8 -anchor nw -relief raised
274 pack $fgraph -side right -fill both -expand 1
276 # now, autoscaling may not be the best. Lets try use the standard
277 # deviation for the data points that we have stored right now.
278 calc_best_scale $item ;# returns calc values, or "" if not enough data
280 $fgraph yaxis configure -max $scale_ymax -min $scale_ymin
282 # add day of the week if using the history command
284 $fgraph xaxis configure -loose 1 -title "" -command {my_clock_format "%d/%m %H:%M"}
286 $fgraph xaxis configure -loose 1 -title "" -command {my_clock_format %H:%M}
289 $fgraph element create line
290 $fgraph element configure line \
291 -label $item -color $item_color($item) -symbol "" \
292 -xdata V_x_$item -ydata V_y_$item
294 # puts "data are now [set V_y_[set item](:)]"
296 button .fullscale$item.col1.ok -text "close" -relief flat -underline 0 -bd 0 \
297 -width 6 -command "destroy .fullscale$item ; return"
298 pack .fullscale$item.col1.ok -side bottom
300 # create re-scaling button
302# button .fullscale$item.col1.scale1 -text "AutoScale" -relief flat -underline 0 -bd 0 \
303# -width 6 -font 6x12 -command "scale_single_window Auto $item"
304# pack .fullscale$item.col1.scale1 -side top
305# button .fullscale$item.col1.scale2 -text "ReScale" -relief flat -underline 0 -bd 0 \
306# -font 6x12 -width 6 -command "scale_single_window Rescale $item"
307# pack .fullscale$item.col1.scale2 -side top
310 # trial code - scale menu:
311 menubutton .fullscale$item.col1.scale_gen -text "Scaling" -menu .fullscale$item.col1.scale_gen.mnu \
313 menu .fullscale$item.col1.scale_gen.mnu
314 .fullscale$item.col1.scale_gen.mnu add command -command "scale_single_window Manual $item 1" \
315 -label "Manual Scale"
316 .fullscale$item.col1.scale_gen.mnu add command -command "scale_single_window Rescale $item 1" \
318 .fullscale$item.col1.scale_gen.mnu add command -command "scale_single_window Auto $item 1" \
320 pack .fullscale$item.col1.scale_gen -side top
323 # create information button
324 button .fullscale$item.col1.info -text "Info/Help" -relief flat -underline 0 -bd 0 \
325 -width 6 -command "show_item_info $item"
326 pack .fullscale$item.col1.info -side top
328 # create hard copy pull down menu:
329 menubutton .fullscale$item.col1.hard -text "HardCopy" -relief flat -underline 0 -bd 0 \
330 -menu .fullscale$item.col1.hard.mnu -relief raised
332 set hardcopy_menu [ menu .fullscale$item.col1.hard.mnu]
334 $hardcopy_menu add command -command "hardcopy ps $fgraph" -label "ps file"
335 $hardcopy_menu add command -command "hardcopy jpg $fgraph" -label "jpg file"
336 $hardcopy_menu add command -command "hardcopy gif $fgraph" -label "gif file"
337 $hardcopy_menu add command -command "hardcopy png $fgraph" -label "png file"
339 pack .fullscale$item.col1.hard
340 # bindings for the zooming function.
341 bind $fgraph <ButtonPress-1> "zoom_select %W %x %y start"
342 bind $fgraph <ButtonRelease-1> "zoom_select %W %x %y stop"
351#======================================================================
352# GRAPH ALL ON FULL SCALE (AS ABOVE), BUT PACKED TOGETHER
353#======================================================================
355proc show_all_full_scale { } {
357 global item_list ;# list of all items to plot
358 global item_color ;# colour associated with item
359 global scale_ymin scale_ymax ;# present best y-scale
360 global winsize_x winsize_y ;# size of toplevel and graph windows
363 global display_item_cnt ;# pointer to start of 5 items to display
365 global item_counter_text ;# copy of display_item but for label
366 global fix_y_scale ;# whether or not mouse zoom changes y-scale
369 # check if window exist already - if so, destroy the graphs on it.
370 if { [winfo exists .fullscale_main ] } {
371 foreach item $item_list {
372 set full_name .fullscale_main.fullscale$item
373 if {[winfo exists $full_name]} { destroy $full_name}
376 toplevel .fullscale_main
377 wm title .fullscale_main "zoom using left-mouse-drag"
378 wm geometry .fullscale_main +[winfo rootx .]+[winfo rooty .]
381 #if we have more than 4 items provide skip buttons
382 if { [llength $item_list] > 4} {
383 if {![winfo exist .fullscale_main.row1]} {
384 if {$debug_code} { puts "Creating top row << >> "}
385 frame .fullscale_main.row1 -relief ridge -bd 3 -height 0.3i
387 button .fullscale_main.row1.prev1 -text "< " -command {
388 incr display_item_cnt -4
391 button .fullscale_main.row1.next1 -text "> " -command {
392 incr display_item_cnt 4
395 button .fullscale_main.row1.prev2 -text "<<" -command {
396 incr display_item_cnt -8
399 button .fullscale_main.row1.next2 -text ">>" -command {
400 incr display_item_cnt 8
403 button .fullscale_main.row1.quit -text "exit" -command {destroy .fullscale_main}
404 label .fullscale_main.row1.number -textvariable item_counter_text
406 button .fullscale_main.row1.fixy -text "Freeze Y scale" \
408 set fix_y_scale [expr !$fix_y_scale] ; # invert toggle
410 .fullscale_main.row1.fixy configure -bg red -activebackground red2
412 .fullscale_main.row1.fixy configure -bg grey -activebackground "#d6d8d6"
416 pack .fullscale_main.row1.fixy -side right
420 pack .fullscale_main.row1.prev2 -side left
421 pack .fullscale_main.row1.prev1 -side left
422 pack .fullscale_main.row1.quit -side left
423 pack .fullscale_main.row1.number -side right -fill x -padx 20
424 pack .fullscale_main.row1.next2 -side right
425 pack .fullscale_main.row1.next1 -side right
427 pack .fullscale_main.row1 -side top -expand 1
432 # make sure we dont over run the list
433 if { $display_item_cnt < 0 } { set display_item_cnt 0}
434 if { $display_item_cnt > [expr [llength $item_list]-4] } {
435 set display_item_cnt [expr [llength $item_list] -4 ]
441 puts "Debug: item to display list counter is $display_item_cnt"
442 puts "Debug: item list length is [llength $item_list] "
445 set last_item [expr $display_item_cnt + 3]
449 set item_counter_text "[expr $display_item_cnt+1] to [expr $last_item+1] out of [llength $item_list]"
451 foreach item [lrange $item_list $display_item_cnt $last_item] {
455 if {$n_items>4} { break }
457 set full_name .fullscale_main.fullscale$item
461 # split screen in two parts -
462 frame $full_name.col1 ;# create two columes - rhs for graph
463 frame $full_name.col2 ;# left hand side for buttons.
464 pack $full_name.col1 -side left
465 pack $full_name.col2 -side right -fill both -expand 1
467 set fgraph $full_name.col2.graph
469 graph $fgraph -title "" -relief ridge -bd 3 -background "#c8f8ce"
470 #-plotbackground black
471 # switch cross hairs on. For some reason $fgraph crosshairs on doesnt work?
473 Blt_Crosshairs $fgraph
476 $fgraph configure -width 5.0i -height 2.0i ;# configure it a little
477 $fgraph legend configure -position @80,8 -anchor nw -relief raised
479 pack $fgraph -side right -fill both -expand 1
481 # now, autoscaling may not be the best. Lets try use the standard
482 # deviation for the data points that we have stored right now.
484 calc_best_scale $item ;# returns calc values, or "" if not enough data
486 $fgraph yaxis configure -max $scale_ymax -min $scale_ymin
488 # add day of the week if using the history command
490 $fgraph xaxis configure -loose 1 -title "" -command {my_clock_format "%d/%m %H:%M"}
492 $fgraph xaxis configure -loose 1 -title "" -command {my_clock_format %H:%M}
495 $fgraph element create line
496 $fgraph element configure line \
497 -label $item -color $item_color($item) -symbol "" \
498 -xdata V_x_$item -ydata V_y_$item
502 button $full_name.col1.ok -text "close" -width 6 -relief flat -underline 0 -bd 0 \
503 -command "destroy $full_name ; return"
504 pack $full_name.col1.ok -side bottom
506 # create re-scaling button
507# button $full_name.col1.scale1 -text "AutoScale" -width 6 -font 6x12 \
508# -command "scale_single_window2 Auto $item"
509# pack $full_name.col1.scale1 -side top
510# button $full_name.col1.scale2 -text "ReScale" -font 6x12 -width 6 \
511# -command "scale_single_window2 Rescale $item"
512# pack $full_name.col1.scale2 -side top
513# pack $full_name.col1.scale2 -side top
516 # trial code - scale menu:
517 menubutton $full_name.col1.scale_gen -text "Scaling" -menu $full_name.col1.scale_gen.mnu \
519 menu $full_name.col1.scale_gen.mnu
520 $full_name.col1.scale_gen.mnu add command -command "scale_single_window Manual $item 2" \
521 -label "Manual Scale"
522 $full_name.col1.scale_gen.mnu add command -command "scale_single_window Rescale $item 2" \
524 $full_name.col1.scale_gen.mnu add command -command "scale_single_window Auto $item 2" \
526 pack $full_name.col1.scale_gen -side top
531 # create information button
532 button $full_name.col1.info -text "Info/Help" -width 6 -relief flat -underline 0 -bd 0 \
533 -command "show_item_info $item"
534 pack $full_name.col1.info -side top
536 # create hard copy pull down menu:
537 menubutton $full_name.col1.hard -text "HardCopy" -relief flat -underline 0 -bd 0 \
538 -menu $full_name.col1.hard.mnu
540 set hardcopy_menu [ menu $full_name.col1.hard.mnu]
542 $hardcopy_menu add command -command "hardcopy ps $fgraph" -label "ps file"
543 $hardcopy_menu add command -command "hardcopy jpg $fgraph" -label "jpg file"
544 $hardcopy_menu add command -command "hardcopy gif $fgraph" -label "gif file"
545 $hardcopy_menu add command -command "hardcopy png $fgraph" -label "png file"
547 pack $full_name.col1.hard
549 # bindings for the zooming function.
550 bind $fgraph <ButtonPress-1> "zoom_select %W %x %y start"
551 bind $fgraph <ButtonRelease-1> "zoom_select %W %x %y stop"
552 pack $full_name -side top -expand 1 -fill both
561#proc popup_next_prev_window { } {
563# global display_item_cnt
565# toplevel .disp_next -background green
567# wm geometry .disp_next \
568# +[winfo rootx .fullscale_main]+[winfo rooty .fullscale_main]
569# label .disp_next.title -text "Prev 5 or Next 5 " -background green
570# button .disp_next.prev -text "<<" -command {
571# incr display_item_cnt -5
574# button .disp_next.next -text ">>" -command {
575# incr display_item_cnt 5
578# button .disp_next.quit -text "exit" -command {destroy .disp_next}
579# pack .disp_next.title -side top
580# pack .disp_next.prev -side left
581# pack .disp_next.quit -side left
582# pack .disp_next.next -side right
591#======================================================================
592# ZOOM ON SELECTED GRAPHS USING MOUSE
593#======================================================================
594proc zoom_select {window x y point} {
599 if {$point=="start"} {
600 set zoom_coor(corner1) [$window invtransform $x $y]
602 } elseif {$point=="stop"} {
603 set zoom_coor(corner2) [$window invtransform $x $y]
605 tk_messageBox -message "Error: wrong parameter to zoom routine"
609 # ok have corner 1 and 2
612 if { [lindex $zoom_coor(corner1) 0] < [lindex $zoom_coor(corner2) 0] } {
613 $window xaxis configure -min [lindex $zoom_coor(corner1) 0] -max [lindex $zoom_coor(corner2) 0]
617 if { [lindex $zoom_coor(corner1) 1] < [lindex $zoom_coor(corner2) 1] } {
618 $window yaxis configure -min [lindex $zoom_coor(corner1) 1] -max [lindex $zoom_coor(corner2) 1]
620 $window yaxis configure -max [lindex $zoom_coor(corner1) 1] -min [lindex $zoom_coor(corner2) 1]
627#================================================================
628# HARDCOPY TO POSTSCRIPT/JPG/PNG/GIF FILE
629#================================================================
631proc hardcopy {type window} {
632 $window postscript configure -paperwidth 6.5i -paperheight 8i \
634 $window postscript output stripchart.ps
637 tk_messageBox -message "Postscript output to file stripchart.ps"
642 catch "exec convert stripchart.ps stripchart.jpg" err
644 tk_messageBox -message "JPEG output to file stripchart.jpg"
647 tk_messageBox -message "Error: $err.\n Output defaults to ps file stripchart.ps"
652 catch "exec convert stripchart.ps stripchart.png" err
654 tk_messageBox -message "PNG output to file stripchart.png"
657 tk_messageBox -message "Error: $err.\n Output defaults to ps file stripchart.ps"
663 catch "exec convert stripchart.ps stripchart.gif" err
665 tk_messageBox -message "GIF output to file stripchart.gif"
668 tk_messageBox -message "Error: $err.\n Output defaults to ps file stripchart.ps"
677#================================================================
678# RESET SCALE ON EXANDED WINDOW
679#================================================================
681proc scale_single_window {scale_mode item window} {
683 global scale_ymax scale_ymin ;# returned and calculated values
685# window =1 for the individual guys =2 for the stacked guys
687 if {$window==1} { set fgraph .fullscale$item.col2.graph }
688 if {$window==2} { set fgraph .fullscale_main.fullscale$item.col2.graph }
690 switch -glob -- $scale_mode {
691 "Auto" { set scale_ymax "" ; set scale_ymin "" }
692 "Rescale" { calc_best_scale $item} ;# this returns new best values
694 toplevel .inputbox ;# make a seperate window for this
695 # put new window at (x,y) of root window:
696 wm geometry .inputbox +[winfo rootx .]+[winfo rooty .]
702 grid .inputbox.row1 -row 1
703 grid .inputbox.row2 -row 2
704 grid .inputbox.row3 -row 3
706 label .inputbox.row1.startlab -text "Ymin = " -height 2
707 entry .inputbox.row1.start -textvariable scale_ymin -width 40
708 pack .inputbox.row1.start -side right
709 pack .inputbox.row1.startlab -side left
711 label .inputbox.row2.startlab -text "Ymax = " -height 2
712 entry .inputbox.row2.start -textvariable scale_ymax -width 40
713 pack .inputbox.row2.start -side right
714 pack .inputbox.row2.startlab -side left
717 # create a button which, when clicked, will read the box, then destroy the box
718 button .inputbox.row3.ok -text "ok" -command {
719 .inputbox.row1.start get ;# gets read into var.
722 button .inputbox.row3.cancel -text "cancel" -command {
726 pack .inputbox.row3.ok -side left
727 pack .inputbox.row3.cancel -side left
728 tkwait window .inputbox ;# wait until its been destroyed
735 $fgraph yaxis configure -min $scale_ymin -max $scale_ymax
736 $fgraph xaxis configure -min "" -max ""
741# copy of the routine, but called by the stacked detail graphs
742#proc scale_single_window2 {scale_mode item} {
743# global scale_ymax scale_ymin ;# returned and calculated values
744# set fgraph .fullscale_main.fullscale$item.col2.graph
745# switch -glob -- $scale_mode {
746# "Auto" { set scale_ymax "" ; set scale_ymin "" }
747# "Rescale" { calc_best_scale $item} ;# this returns new best values
750# $fgraph yaxis configure -min $scale_ymin -max $scale_ymax
751# $fgraph xaxis configure -min "" -max ""
757#==================================================================
758# CALCULATE Y-SCALE USING DATA VALUE STANDARD DEVIATIONS
759#==================================================================
761proc calc_best_scale { item } {
762# now, autoscaling may not be the best. Lets try use the standard
763# deviation for the data points that we have stored right now.
766 global scale_ymin scale_ymax
768 if { [vector expr length(V_y_$item)] > 10 } {
769 set stand_dev [ vector expr sdev(V_y_$item) ] ;# get standard deviation
770 set mean [ vector expr mean(V_y_$item) ] ;# get the mean
772 set scale_ymin [expr $mean - 8.* $stand_dev]
773 set scale_ymax [expr $mean + 8.* $stand_dev]
775 if { [expr abs($scale_ymin- $scale_ymax) ] < 10.E-10 } {
776 set scale_ymin [expr $mean - 1.]
777 set scale_ymax [expr $mean + 1.]
781 if { [expr abs($scale_ymin)] <10.E-20} {
782 set scale_ymin [expr $mean - 1.]
784 if { [expr abs($scale_ymax)] <10.E-20} {
785 set scale_ymax [expr $mean + 1.]
792 if { $scale_ymin >= $scale_ymax } {
793# tk_messageBox -message "warning: data is constant - no y-scaling \
794# possible for $item. \n\n ymax/min = $scale_ymin $scale_ymax \n\
795# Standard deviation = $stand_dev"
796# puts "data are now [set V_y_[set item](:)]"
809#====================================================================
811#====================================================================
813proc wait_ms {mill_sec} {
814 set mill_sec [expr $mill_sec/100.0]
815 for {set count 0 } { $count < $mill_sec} { incr count} {
822#======================================================================
823# SET THE SCROLL TIME INTERVAL USING RADIO BUTTONS
824#======================================================================
826proc new_scroll_time { } {
829# did the button already get pressed ?
830 if [winfo exists .main.radio ] {
839 set radio .main.radio
841 radiobutton $radio.radio1 -text "100 sec " -relief flat \
842 -variable time_limit -value 100.
843 radiobutton $radio.radio2 -text "5 min " -relief flat \
844 -variable time_limit -value [expr 5*60.]
845 radiobutton $radio.radio3 -text "1 hrs " -relief flat \
846 -variable time_limit -value [expr 60*60.]
847 radiobutton $radio.radio4 -text "5 hrs " -relief flat \
848 -variable time_limit -value [expr 5*60*60.]
849 radiobutton $radio.radio5 -text "12 hrs " -relief flat \
850 -variable time_limit -value [expr 12*60*60.]
851 button $radio.ok -text "ok" -command "destroy $radio"
854 for {set i 1} {$i<6} {incr i} {
864#=====================================================================
865# SHOW INFO ON INDIVUDUAL ITEM
866#=====================================================================
868proc show_item_info {item} {
872 # put a an <ok> button on it:
873 button .item_info.ok -text "OK" -command {destroy .item_info ; return}
874 pack .item_info.ok -side bottom
876 # put the text in the window:
877 message .item_info.mess -width 6i -text \
878 "note: <spaces> are substituted by _ as are \\+- and % signs \n\n \
879 item name : $equip_name/ $item \n\n \
880 Available functions: \n\n \
881 Click-and-drag Left button to zoom time axis.\
882 Click Rescale to return to normal mode\n \
883 Autoscale = optimun scale for graph size \n \
884 ReScale = scale calculate using data standard deviation\n \
885 HardCopy = output to JPEG/PS/PNG etc\n \
886 Close = close this window\n"
896#=======================================================================
897# LOCATE GRAPH ITEM POINTED TO BY MOUSE
898#=======================================================================
900proc mouse_find_item {window x y } {
903 # transform X-win coordinates to graph coordinates.
904 set graph_coor [$window invtransform $x $y]
905 set x_coor [lindex $graph_coor 0]
906 set y_coor [lindex $graph_coor 1]
908 # loop over entire list of data find the closest point and display
909 # the item belonging to that point.
911 set closest [expr 10000000000000000.0]
913 foreach item $item_list {
915 global V_y_plot_$item
917 vector create dist ;# dummy vector
918 dist expr "(V_x_$item- $x_coor)^2 + (V_y_plot_$item - $y_coor)^2 "
920 # rember smallest element
921 if { [vector expr min(dist)] < $closest} {
922 set closest [vector expr min(dist)]
923 set closest_item $item
929 # call the graph spawn routine.
930 select_graph $closest_item
935#========================================================================
936# READ THE OUTPUT OF MHIST, ALLOW SELECTION OF DATA AND GRAPH ** MHIST **
937#========================================================================
938proc read_mhist_file {open_file } {
940 global pick_event_var
942 global history_time history_interval history_unit history_amount
945 global item_fname item_fields item_pattern item_equation
946 global item_color item_max item_min item_list
953 global event_ids_info ; #mhist event ID and name
954 global event_var ; #varialbe name
957 global debug_code ; #general code debugging
958 global button_toggle ; #use to toggle lots of variables on/off simul.
960 global mhist_path ; # place to find mhist
961 global selected_items ; # list of history items from listbox selection
963 global hist_file ; # name of history file to open
964 global file_pref ; # /tmp file prefix
966 global file_path ; # path to the actual history files
975 if {![find_newest_mhist]} return ; # locate mhist executable
978 if {$debug_code} {puts "Debug: in routine read mhist file"}
980# this is the FILE read version -
981#i.e. implicitly gets user to select a file.
982# Then select the EVENT ID
983# Then select items to be displayed
984 if { [llength $item_list] >0} {
985 clean_list_and_vectors_and_widgets ;# remove all things associate
986 ;# with previous data
990 # get a new file or use the old ?
992 if {$debug_code} {puts "Debug: file path is $file_path"}
993 # here we go..a *new* widget
994 set types {{"History files .hst" {.hst}}}
995 set hist_file [tk_getOpenFile -filetypes $types -initialdir $file_path]
996 # but have to remember the path for the next call:
997 if {$hist_file !=""} { set file_path [file dirname $hist_file] }
1000 if {$hist_file==""} {
1001 tk_messageBox -message "You need to open a file first \n"
1006 if {$debug_code} {puts "Debug: file path is now $file_path"}
1007 if ![string compare $hist_file ""] return
1008 # ok, so we have the file name. Now repeat the previous excercicse
1009 # of getting the event ID.
1010 catch "exec rm -f /tmp/${file_pref}mhist" error_var
1011 set exec_string "$mhist_path/mhist -f $hist_file -l"
1013 if {$debug_code} {puts "debug1: exec string is $exec_string"}
1015 catch "exec $exec_string > /tmp/${file_pref}mhist" error_var
1016 if {$error_var !="" } {
1017 tk_messageBox -message "Could not start mhist (*path problem ?) \n \
1018 $error_var \n. Command line was \n $exec_string"
1022 # assume the mhist out put is there and get event selection
1024 if {$debug_code} {puts "debug: calling get_mhist_list"}
1025 if {![get_mhist_list]} return
1027 if {$debug_code} {puts "debug: calling select_event_id"}
1028 if {[select_event_id]=="do_exit"} return
1031 # if an element is actually it self an array, expand that element to show
1032 # all array elements as seperate event variables
1033 if {[deal_with_array_vars]=="do_exit"} return
1036 # now do all the item selection stuff.
1037 if {$debug_code} {puts "debug: calling select_event_items"}
1038 if {[select_event_items old_file]=="do_exit"} return
1040 # now set the pick_event_var variables, just like before but using the results
1041 # from the list box retrieved from routine select_event_items
1042 # selected_items is only the index to the stuff that was picked from the scroll
1044 foreach i $selected_items {
1045 set var [ lindex $event_var($event_choice) $i]
1046 set pick_event_var($var) 1
1047 if {$debug_code} {puts "Have picked index $i and name is $var"}
1050 # now calculate history time (needed only for plotting here
1051 switch -glob -- $history_unit {
1052 "days" {set history_time [expr $history_amount *1 ] }
1053 "weeks" {set history_time [expr $history_amount *7 ] }
1054 "months" {set history_time [expr $history_amount *30 ] }
1057 # when opening old file, assume start date (-s) = name of file
1058 # end date (-p) = calculated from user input above
1061 # calc start date from file name: (hist_file)
1062 # unfortunately, Stephan uses yymmdd.hst. Oh well.
1063 # split list at the '.'
1064 # ah, but stephan has fixed the file names now
1065 # Here analyze the file name to get starting date.
1067 set hist_file [lindex [split $hist_file /] end]
1068 set date_part [lindex [split $hist_file .] 0]
1071 if { [string range $date_part 0 1]=="97" || [string range $date_part 0 1]=="98" } {
1072 set start_time $date_part
1074 set day_part [string range $date_part 4 5]
1075 set mon_part [string range $date_part 2 3]
1076 set yre_part [string range $date_part 0 1]
1077 # set start_time $day_part$mon_part$yre_part
1078 set start_time $yre_part$mon_part$day_part
1081 # ok, do the end part.
1082 if {$history_unit =="until_now"} {
1083 set stop_time [clock format [clock seconds] -format "%d%m%y"]
1085 # gets tough. Must calculate a new day from old date and interval
1086 if {$debug_code} {puts "debug: calling calc_history_stop_time $day_part"}
1087 set stop_time [calc_history_stop_time $day_part $mon_part $yre_part]
1091 # now, now filter out which events we dont want and repeatedly call mhist
1092 # to get what we want.
1093 # -b = time in seconds.
1097 foreach var $event_var($event_choice) {
1100 wm title . "Loading data......... $var"
1101 .main.middle.strip_chart configure -background red
1106 # was this guy enabled ?
1107 if { !$pick_event_var($var)} { continue }
1110 # check if it was an array - if so, add -i option and remove brackets
1111 if {[string match {*\[*\]} $var]} {
1112 if {$debug_code} {puts "Debug: back in read mhist - array var case"}
1113 # extract index number:
1114 set num_elem [string range $var [string last "\[" $var] [string last "\]" $var]]
1115 set num_elem [string range $num_elem 1 [expr [string length $num_elem] -2]]
1117 set new_var [string range $var 0 [expr [string last "\[" $var] -1]]
1118 # add -i to exec_string
1119 if {$debug_code} {puts "Debug: array index is $num_elem and new name $new_var"}
1121 "$mhist_path/mhist -b -s $start_time \
1122 -p $stop_time -t $history_interval -e $event_choice -v \"$new_var\" -i $num_elem"
1126 "$mhist_path/mhist -b -s $start_time \
1127 -p $stop_time -t $history_interval -e $event_choice -v \"$var\" "
1131 # note the surround by quotes
1132 # now add the path name to the files, in case we are not in the PWD.
1133 if {$file_path !=""} {
1134 set exec_string "$exec_string -z $file_path"
1137 # if we are not debugging....go for it.
1138 if { [string compare $debug "mhist"] } {
1139 if {$debug_code} {puts "debug2: Exec string is: $exec_string"}
1140 catch {exec rm -f /tmp/${file_pref}mhist_data} error_var
1141 catch "exec $exec_string > /tmp/${file_pref}mhist_data" error_var
1144 if {$error_var !=""} {
1145 tk_messageBox -message "problem: error from mhist \n $exec_string \n $error_var\n"
1150 # check if MHIST was busy recovering the index files. This should only happen
1151 # once. Mhist does then give the data, but it's easier to run it again I think
1152 set file_hndl [open "/tmp/${file_pref}mhist_data" r ]
1153 if {![eof $file_hndl]} {
1154 gets $file_hndl string
1155 if {[string first "Recovering" $string]!=-1} {
1156 if {$debug_code} {puts "Ooops - mhist recovered index files ! -repeat extraction:"}
1157 if {$debug_code} {puts "Exec string is $exec_string"}
1158 catch {exec rm -f /tmp/${file_pref}mhist_data} error_var
1159 catch "exec $exec_string > /tmp/${file_pref}mhist_data" error_var
1162 tk_messageBox -message "problem: mhist output /tmp/${file_pref}mhist_data emptry \n \
1163 $exec_string \n $error_var"
1167 # end of index generation checking
1171 # get ready to create the vector names
1173 set item [filter_bad_chars $item] ;# remove spaces, slashes, etc etc
1175 # create the new vectors
1177 vector create V_x_$item
1178 vector create V_y_$item
1179 vector create V_y_plot_$item
1181 # get the data and read into BLT vectors as usual.
1182 set file_hndl [open "/tmp/${file_pref}mhist_data" r ]
1184 while {![eof $file_hndl]} {
1185 gets $file_hndl string
1187# if { $debug_code } { puts "From file got string $string " }
1188 if { [llength $string] == 2} {
1189 set x_val [string toupper [lindex $string 0]]
1190 set y_val [string toupper [lindex $string 1]]
1191 if { [string first "NAN" $x_val]==-1 && [string first "NAN" $y_val]==-1} {
1192# if {$debug_code} {puts "Adding to item $item value (x,y) $x_val $y_val " }
1193 V_x_${item} append $x_val
1194 V_y_${item} append $y_val
1196 puts "Stripchart: - Found NAN number in MHIST data for $item -set to 0 "
1197 V_x_${item} append 0
1198 V_y_${item} append 0
1200# set V_x_${item}(++end) [lindex $string 0]
1201# set V_y_${item}(++end) [lindex $string 1]
1203 # check for error from mhist:
1204 } elseif {[llength $string] >=2 } {
1205 if {[tk_messageBox -type abortretryignore \
1206 -message "problem: looking for data.\n $exec_string\
1207 but got from mhist:\n $string\n\
1208 Ignore to skip this item \n\
1209 Abort to cancel all items \n"]=="ignore"} {
1223 if {!$ignore_item} {
1224 # fill in the same info we might have gotten from a .conf file:
1225 # add to the list of items plotted
1226 lappend item_list $item
1228 set item_color($item) [get_new_color]
1230 # now for these data calculate appropiate max/min values, as we were
1231 # given them from the .conf file:
1232 if { [vector expr length(V_y_$item)] <= 1} {
1233 tk_messageBox -default ok -message "Not enough data read for plotting" -type ok
1237 if { [vector expr length(V_y_$item)] > 10 } {
1238 set stand_dev [ vector expr sdev(V_y_$item) ] ;# get standard deviation
1239 set mean [ vector expr mean(V_y_$item) ] ;# get the mean
1241 set item_min($item) [expr $mean - 8.* $stand_dev]
1242 set item_max($item) [expr $mean + 8.* $stand_dev]
1243# puts "before checl: min and max are $item_max($item) $item_min($item) $mean"
1245 if { [expr abs($item_min($item)-$item_max($item))] < 10.E-10 } {
1246 set item_min($item) [expr $mean - 1.]
1247 set item_max($item) [expr $mean + 1.]
1249 if { [expr abs($item_min($item))] <10.E-20} {
1250 set item_min($item) [expr $mean - 1.]
1252 if { [expr abs($item_max($item))] <10.E-20} {
1253 set item_max($item) [expr $mean + 1.]
1255# puts "min and max are $item_max($item) $item_min($item)"
1257 set mean [ vector expr mean(V_y_$item) ]
1258 set item_min($item) [expr $mean - 100.]
1259 set item_max($item) [expr $mean + 100.]
1260# puts "min and max are $item_max($item) $item_min($item) --------"
1264 # from this max/min value, calculate the plotted normalized histo values:
1265 # do a vector calculation on this new guy.
1268 expr "(V_y_$item - $item_min($item)) / ($item_max($item)-$item_min($item))"
1270 # finally associate/create a graph item for this guy
1271 if {! [$strip_chart element exists line_$item]} {
1272 $strip_chart element create line_$item
1274 $strip_chart element configure line_$item -label "" -color $item_color($item) -symbol ""
1275 # now hot-link it to the new graph line
1276 $strip_chart element configure line_$item -xdata V_x_$item -ydata V_y_plot_$item
1277 # change the labelling format on the x-axis if plotting more then one day
1278 if {$history_time >= 1} {
1279 $strip_chart xaxis configure -command {my_clock_format "%d/%m %H:%M"}
1281 $strip_chart xaxis configure -command {my_clock_format "%H:%M"}
1284 # create the pull down item menu. Also align the text string
1285 set blank_string " "
1286 set item_length [string length $item]
1287 if {$item_length > 13} {set item_length 13}
1288 set menu_string "$item [string range $blank_string 1 [expr 13 - $item_length] ]"
1289 append menu_string $item_color($item)
1290 $select_men add command -command "select_graph $item" -label $menu_string
1301#=========================================================================
1302# READ PRESENT MHIST DATA - this routine is very simular to the above
1303# but subtle difference with respect to picking the start/stop time
1304#=========================================================================
1305proc read_present_mhist { } {
1307 global pick_event_var
1309 global history_time history_interval history_unit history_amount
1312 global item_fname item_fields item_pattern item_equation
1313 global item_color item_max item_min item_list
1321 global event_ids_info ;#mhist event ID and name
1322 global event_var ;#varialbe name
1324 global debug_code ; #general code debugging
1326 global button_toggle ; #use to toggle lots of variables on/off simul.
1328 global mhist_path ; # place to find mhist
1329 global selected_items ; # list of history items from listbox selection
1331 global file_pref ; #/tmp tmp file prefix
1332 global file_path ; # path to history files.
1334 if {![find_newest_mhist]} return ; # locate mhist executable
1336 if {$debug_code} {puts "Debug: in routine read present_mhist file"}
1343 if { [llength $item_list] >0} {
1344 if {$debug_code} {puts "Debug: calling clean_list_and_vectors"}
1345 clean_list_and_vectors_and_widgets ;# remove all things associate
1346 ;# with previous data
1350# note: string compare is like 'c' - 0 == string match !!!
1351# so if NOT debugging, execute mhist:
1353 if {$file_path !=""} {
1354 set exec_string "$mhist_path/mhist -l -z $file_path > /tmp/${file_pref}mhist"
1356 set exec_string "$mhist_path/mhist -l > /tmp/${file_pref}mhist"
1359 if { [string compare $debug "mhist"] } {
1361 puts "Executing mhist command: $exec_string"
1363 catch "exec rm -f /tmp/${file_pref}mhist" error_var
1364 catch "exec $exec_string" error_var
1367 if {$error_var !="" } {
1368 tk_messageBox -message "Could not start mhist (path problem ?) \n $error_var"
1372 # assume the mhist out put is there. Retrieve the ID list
1373 if {![get_mhist_list] } return
1375 # do selection of the event_id:
1376 if {$debug_code} {puts "Calling select_event_id"}
1377 if {[select_event_id] =="do_exit"} return
1379 # if an element is actually it self an array, expand that element to show
1380 # all array elements as seperate event variables i.e. DATA[5] become 5 seperate items in the list.
1381 # see the -i option in mhist
1382 if {$debug_code} {puts "Calling deal with arrays"}
1383 if {[deal_with_array_vars]=="do_exit"} return
1385 if {$debug_code} {puts "Calling select_event_items"}
1386 if {[select_event_items today]=="do_exit"} return
1388 # now set the pick_event_var variables, just like before but using the results
1389 # from the list box.
1392 foreach i $selected_items {
1393 set var [ lindex $event_var($event_choice) $i]
1394 set pick_event_var($var) 1
1398 # now calculate history time (assume todays history
1399 switch -glob -- $history_unit {
1400 "days" {set history_time [expr $history_amount *1 ] }
1401 "weeks" {set history_time [expr $history_amount *7 ] }
1402 "months" {set history_time [expr $history_amount *30 ] }
1405 # deal with the open file possibility
1406 # when opening old file, assume start date (-s) = name of file
1407 # end date (-p) = calculated from user input above
1409 # now, now filter out which events we dont want and repeatedly call mhist
1410 # to get what we want.
1411 # -b = time in seconds.
1414 foreach var $event_var($event_choice) {
1416 wm title . "Loading data......... $var"
1417 .main.middle.strip_chart configure -background red
1420 # was this guy enabled ?
1421 if { !$pick_event_var($var)} { continue }
1423 # was it an array data word (must use -i to get the actual value)
1424 if {[string match {*\[*\]} $var]} {
1425 if {$debug_code} {puts "Debug: back in read mhist - array var case"}
1426 # extract index number:
1427 set num_elem [string range $var [string last "\[" $var] [string last "\]" $var]]
1428 set num_elem [string range $num_elem 1 [expr [string length $num_elem] -2]]
1430 set new_var [string range $var 0 [expr [string last "\[" $var] -1]]
1431 # add -i to exec_string
1432 if {$debug_code} {puts "Debug: array index is $num_elem and new name $new_var"}
1435 "$mhist_path/mhist -b -d $history_time -t $history_interval -e $event_choice -v \"$new_var\" -i $num_elem"
1439 "$mhist_path/mhist -b -d $history_time -t $history_interval -e $event_choice -v \"$var\" "
1444 if {$file_path !=""} {
1445 set exec_string "$exec_string -z $file_path"
1449 # if we are not debugging....go for it.
1450 if { [string compare $debug "mhist"] } {
1451 if {$debug_code} {puts "Debug5: exec string is: $exec_string > /tmp/${file_pref}mhist_data"}
1452 catch {exec rm -f /tmp/${file_pref}mhist_data} error_var
1453 catch "exec $exec_string > /tmp/${file_pref}mhist_data" error_var
1456 if {$error_var !=""} {
1457 tk_messageBox -message "problem: error from mhist \n $exec_string \n $error_var"
1462 # get ready to create the vector names
1464 set item [filter_bad_chars $item] ;# remove spaces, slashes, etc etc
1467 # create the new vectors
1469 vector create V_x_$item
1470 vector create V_y_$item
1471 vector create V_y_plot_$item
1475 # get the data and read into BLT vectors as usual.
1476 set file_hndl [open "/tmp/${file_pref}mhist_data" r ]
1478 while {![eof $file_hndl]} {
1479 gets $file_hndl string
1480 if { [llength $string] == 2} {
1481 set x_val [string toupper [lindex $string 0]]
1482 set y_val [string toupper [lindex $string 1]]
1483 if { [string first "NAN" $x_val]==-1 && [string first "NAN" $y_val]==-1} {
1484 V_x_${item} append $x_val
1485 V_y_${item} append $y_val
1487 puts "Stripchart: - Found NAN number in MHIST data for $item"
1488 V_x_${item} append 0
1489 V_y_${item} append 0
1491 # Original code has: - which should work, but broke under RH7.2 distr
1492 #set V_x_${item}(++end) [lindex $string 0]
1493 #set V_y_${item}(++end) [lindex $string 1]
1495 } elseif {[llength $string] >=2 } {
1496 tk_messageBox -message "problem: looking for data.\n Send $exec_string \n \
1497 , but found \n $string \n\
1498 Probably means, there really is no file for today's date."
1505 # fill in the same info we might have gotten from a .conf file:
1506 # add to the list of items plotted
1507 lappend item_list $item
1509 set item_color($item) [get_new_color]
1513 puts "Item name $item"
1514 puts "Vector length y [vector expr length(V_y_$item)]"
1515 puts "Vector length x [vector expr length(V_x_$item)]"
1518# now for these data calculate appropiate max/min values, as we were
1519# given them from the .conf file:
1520 if { [vector expr length(V_y_$item)] <= 1} {
1521 tk_messageBox -default ok -message "Not enough data read for plotting" -type ok
1525 if { [vector expr length(V_y_$item)] > 10 } {
1526 set stand_dev [ vector expr sdev(V_y_$item) ] ;# get standard deviation
1527 set mean [ vector expr mean(V_y_$item) ] ;# get the mean
1529 set item_min($item) [expr $mean - 8.* $stand_dev]
1530 set item_max($item) [expr $mean + 8.* $stand_dev]
1533 if { [expr abs($item_min($item)-$item_max($item))] < 10.E-10 } {
1534 set item_min($item) [expr $mean - 1.]
1535 set item_max($item) [expr $mean + 1.]
1537 if { [expr abs($item_min($item))] <10.E-20} {
1538 set item_min($item) [expr $mean - 1.]
1540 if { [expr abs($item_max($item))] <10.E-20} {
1541 set item_max($item) [expr $mean + 1.]
1546 set mean [ vector expr mean(V_y_$item) ]
1547 set item_min($item) [expr $mean - 100.]
1548 set item_max($item) [expr $mean + 100.]
1551 # from this max/min value, calculate the plotted normalized histo values:
1552 # do a vector calculation on this new guy.
1555 expr "(V_y_$item - $item_min($item)) / ($item_max($item)-$item_min($item))"
1557 # finally associate/create a graph item for this guy
1558 if {! [$strip_chart element exists line_$item]} {
1559 $strip_chart element create line_$item
1561 $strip_chart element configure line_$item -label "" -color $item_color($item) -symbol ""
1562 # now hot-link it to the new graph line
1563 $strip_chart element configure line_$item -xdata V_x_$item -ydata V_y_plot_$item
1564 # change the labelling format on the x-axis if plotting more then one day
1565 if {$history_time >= 1} {
1566 $strip_chart xaxis configure -command {my_clock_format "%d/%m %H:%M"}
1568 $strip_chart xaxis configure -command {my_clock_format "%H:%M"}
1571 # create the pull down item menu. Also align the text string
1572 set blank_string " "
1573 set item_length [string length $item]
1574 if {$item_length > 13} {set item_length 13}
1575 set menu_string "$item [string range $blank_string 1 [expr 13 - $item_length] ]"
1576 append menu_string $item_color($item)
1577 $select_men add command -command "select_graph $item" -label $menu_string
1590#===================================================================
1591# DEAL WITH VARIABLES THAT ARE ACTUALLY ARRAYS
1592# expand the actual variable list to include all elements as
1593# seperate variables i.e. MY_AR[4] adds 4 new elements
1594#===================================================================
1595proc deal_with_array_vars { } {
1597 global event_choice # number of the chosen event
1598 global event_var # this is the list of list of variables
1601 if {$debug_code} {puts "Debug: In deal with array vars "}
1605# foreach var $event_var($event_choice) {
1612 foreach var $event_var($event_choice) {
1613 # look for [] in variable name
1614 if {[string match {*\[*\]} $var]} {
1616 # extract the number of elements for this variable:
1617 set num_elem [string range $var [string last "\[" $var] [string last "\]" $var]]
1618 set num_elem [string range $num_elem 1 [expr [string length $num_elem] -2]]
1619 if {$debug_code} {puts "Debug: Found an array variable $var with $num_elem elements"}
1620 # expand the array and add each as a new element
1621 for {set k 0} { $k < $num_elem} {incr k} {
1622 set new_var_name [string range $var 0 [expr [string last "\[" $var] -1]]
1623 set new_var_name ${new_var_name}\[$k\]
1625 # replace the first -
1626 set event_var($event_choice) [lreplace $event_var($event_choice) $i $i $new_var_name]
1628 set event_var($event_choice) [linsert $event_var($event_choice) $i $new_var_name]
1638# foreach var $event_var($event_choice) {
1647#===================================================================
1648# PICK THE ITEMS TO BE PLOTTED
1649#===================================================================
1650proc select_event_items { today_or_file} {
1653 global pick_event_var
1655 global history_time history_interval history_unit history_amount
1659 # ok, now display and pick list of events_names. Use checkbutton
1660 toplevel .select_vars
1661 wm title .select_vars "mhist variable select"
1662 # glue it to the existing window:
1663# wm geometry .select_vars +[winfo rootx .]+[winfo rooty .]
1665 frame .select_vars.col1row1 -relief ridge -bd 3
1666 frame .select_vars.col2row1 -relief ridge -bd 3
1667 frame .select_vars.col1row2 -relief ridge -bd 3
1668 frame .select_vars.col2row2 -relief ridge -bd 3
1669 frame .select_vars.col1row3 -relief ridge -bd 3
1670 frame .select_vars.col2row3 -relief ridge -bd 3
1671 frame .select_vars.col1row4 -relief ridge -bd 3
1672 frame .select_vars.col2row4 -relief ridge -bd 3
1673 frame .select_vars.col1row5 -relief ridge -bd 3
1674 grid .select_vars.col1row1 -row 1 -column 1
1675 grid .select_vars.col2row1 -row 1 -column 2
1676 grid .select_vars.col1row2 -row 2 -column 1
1677 grid .select_vars.col2row2 -row 2 -column 2
1678 grid .select_vars.col1row3 -row 3 -column 1 -columnspan 2
1679 grid .select_vars.col2row3 -row 3 -column 2
1680 grid .select_vars.col1row4 -row 4 -column 1
1681 grid .select_vars.col2row4 -row 4 -column 2
1682 grid .select_vars.col1row5 -row 5 -column 1 -columnspan 2
1684 # trial code for the list box with scroll bar, to replaces the radiobuttons:
1685 # create scroll bar:
1686 scrollbar .select_vars.col1row3.scroll -command ".select_vars.col1row3.listb yview"
1687 # create the list box:
1688 listbox .select_vars.col1row3.listb \
1689 -yscrollcommand ".select_vars.col1row3.scroll set" \
1690 -selectmode extended -height 15
1691 pack .select_vars.col1row3.listb -side left
1692 pack .select_vars.col1row3.scroll -fill y -side right
1696 foreach var $event_var($event_choice) {
1697 if {$debug_code} {puts "List contains $var"}
1698 set pick_event_var($var) 0
1699 .select_vars.col1row3.listb insert end $var
1700 .select_vars.col1row3.listb selection set $i
1704 label .select_vars.col1row5.lab -text "Use <ctrl/shift> for multiple select"
1705 pack .select_vars.col1row5.lab -side bottom -fill x
1709 checkbutton .select_vars.col1row4.all -text "select all/none" -relief ridge \
1710 -variable button_toggle -command {
1712 for {set i 0} {$i< [llength $event_var($event_choice) ]} {incr i} {
1713 if {$button_toggle} {
1714 .select_vars.col1row3.listb selection set $i
1716 .select_vars.col1row3.listb selection clear $i
1721 pack .select_vars.col1row4.all -fill x -expand 1
1723 button .select_vars.col2row4.ok -text "ok" -command {
1724 # for the list box (no more radiobuttons), get the chosen events
1725 set selected_items [.select_vars.col1row3.listb curselection]
1726 destroy .select_vars
1729 button .select_vars.col2row4.cancel \
1730 -text "cancel" -command "set exit_now 1; destroy .select_vars"
1732 pack .select_vars.col2row4.ok -side left
1733 pack .select_vars.col2row4.cancel -side right
1736 # add radio buttons for the time duration and interval
1738 # if using old file, add some text and an 'until now' choice
1739 if {$today_or_file=="old_file"} {
1740 frame .select_vars.col1row0
1741 grid .select_vars.col1row0 -row 0 -column 1 -columnspan 2
1742 label .select_vars.col1row0.text -text "Old history file selected. Displayed \
1743 period is \n\ calculated starting from date of the history file " \
1745 pack .select_vars.col1row0.text
1748 frame .select_vars.col1row1.left ;# subdivide even further: day/weeks etc
1749 frame .select_vars.col1row1.right ;# multiplier
1750 grid .select_vars.col1row1.right -column 2 -row 1
1751 grid .select_vars.col1row1.left -column 1 -row 1
1753 set radio .select_vars.col1row1.left
1756 label .select_vars.col1row1.lab1 -text "History Time:" -anchor center -justify center
1757 grid .select_vars.col1row1.lab1 -row 0 -columnspan 2
1759 label .select_vars.col1row1.left.lab -text "Units"
1760 pack .select_vars.col1row1.left.lab
1762 set radio .select_vars.col1row1.left
1764 # set defualt variable values
1766 set history_unit days
1769 radiobutton $radio.day -text "days" -relief flat -anchor w \
1770 -variable history_unit -value days
1771 pack $radio.day -fill x -expand 1
1772 radiobutton $radio.week -text "weeks" -relief flat -anchor w \
1773 -variable history_unit -value weeks
1774 pack $radio.week -fill x -expand 1
1775 radiobutton $radio.month -text "months" -relief flat -anchor w \
1776 -variable history_unit -value months
1777 pack $radio.month -fill x -expand 1
1779 if {$today_or_file=="old_file"} {
1780 radiobutton $radio.until_now -text "until now" -relief flat -anchor w \
1781 -variable history_unit -value until_now
1782 pack $radio.until_now -fill x -expand 1
1785 # now the day/week/month multiplier
1786 set history_amount 1
1787 label .select_vars.col1row1.right.lab -text "Multiplier"
1788 pack .select_vars.col1row1.right.lab
1790 set radio .select_vars.col1row1.right
1793 radiobutton $radio.1 -text "1" -relief flat -anchor w \
1794 -variable history_amount -value 1
1795 pack $radio.1 -fill x -expand 1
1796 radiobutton $radio.2 -text "2" -relief flat -anchor w \
1797 -variable history_amount -value 2
1798 pack $radio.2 -fill x -expand 1
1799 radiobutton $radio.3 -text "3" -relief flat -anchor w \
1800 -variable history_amount -value 3
1801 pack $radio.3 -fill x -expand 1
1802 radiobutton $radio.4 -text "4" -relief flat -anchor w \
1803 -variable history_amount -value 4
1804 pack $radio.4 -fill x -expand 1
1805 radiobutton $radio.5 -text "5" -relief flat -anchor w \
1806 -variable history_amount -value 5
1807 pack $radio.5 -fill x -expand 1
1811 set history_interval 300 ;# default values
1813 label .select_vars.col2row1.lab -text "History Interval"
1814 pack .select_vars.col2row1.lab
1816 set radio .select_vars.col2row1
1818 radiobutton $radio.1day -text "100 s" -relief flat -anchor w \
1819 -variable history_interval -value 100
1820 pack $radio.1day -fill x -expand 1
1821 radiobutton $radio.2day -text "5 mins" -relief flat -anchor w \
1822 -variable history_interval -value 300
1823 pack $radio.2day -fill x -expand 1
1824 radiobutton $radio.3day -text "30 mins" -relief flat -anchor w \
1825 -variable history_interval -value [expr 30*60]
1826 pack $radio.3day -fill x -expand 1
1827 radiobutton $radio.4day -text "1 hours" -relief flat -anchor w \
1828 -variable history_interval -value [expr 60*60]
1829 pack $radio.4day -fill x -expand 1
1830 radiobutton $radio.5day -text "5 hours" -relief flat -anchor w \
1831 -variable history_interval -value [expr 5*60*60]
1832 pack $radio.5day -fill x -expand 1
1836 # now wait until the window with the variables/times is gone before going on:
1838 tkwait window .select_vars
1840 if {$exit_now} {return "do_exit"}
1847#===================================================================
1848# CALCULATE HISTORTY STOP TIME FROM START DATE AND INTERVAL
1849#===================================================================
1851proc calc_history_stop_time {day_part mon_part yre_part} {
1852 global history_unit history_amount
1854# problem - if the amount starts with 0, like 08 say, tcl
1856# So check whether its two digits:if so trim of leading zero.
1858 if {[string length $day_part] == 2} {
1859 set day_part [string trimleft $day_part 0]
1861 if {[string length $mon_part] == 2} {
1862 set mon_part [string trimleft $mon_part 0]
1865 switch -glob -- $history_unit {
1867 set lday_part [expr $day_part + $history_amount ]
1868 set lmon_part $mon_part
1869 set lyre_part $yre_part
1870 if {$lday_part > 28} {
1871 set lmon_part [incr lmon_part]
1872 set lday_part [expr $lday_part - 28]
1877 set lday_part [expr $day_part + $history_amount*7 ]
1878 set lmon_part $mon_part
1879 set lyre_part $yre_part
1880 if {$lday_part > 28} {
1881 set lmon_part [incr lmon_part]
1882 set lday_part [expr $lday_part - 28]
1886 set lday_part $day_part
1887 set lmon_part [expr $mon_part + $history_amount ]
1888 set lyre_part $yre_part
1889 if {$lmon_part > 12} {
1890 set lyre_part [incr lyre_part]
1891 set lmon_part [expr $lmon_part - 12]
1896 # make sure they are all 2 digits
1897 if {[string length $lday_part] == 1} {
1898 set lday_part "0$lday_part"
1900 if {[string length $lmon_part] == 1} {
1901 set lmon_part "0$lmon_part"
1903 if {[string length $lyre_part] == 1} {
1904 set lyre_part "0$lyre_part"
1907 # ok now put the string back together
1908 #return $lday_part$lmon_part$lyre_part
1909 return $lyre_part$lmon_part$lday_part
1913#=========================================================================
1914# SELECT THE EVENT ID TO DISPLAY IN MHIST
1915#=========================================================================
1918proc select_event_id { } {
1920 global pick_event_var
1922 global event_var ;#variable name
1923 global history_time history_interval history_unit history_amount
1926 global item_fname item_fields item_pattern item_equation
1927 global item_color item_max item_min item_list
1935 global event_ids_info ; #mhist event ID and name
1939 global button_toggle ; #use to toggle lots of variables on/off simul.
1944 # ok, first throw up a selection window for the event id. I guess
1945 # this should be a radio button ?
1947 if [winfo exists .select_event ] {
1948 wm deiconify .select_event
1951 toplevel .select_event
1952 wm title .select_event "mhist event select"
1953 # the next puts the new window at the same position as the root window
1954 wm geometry .select_event +[winfo rootx .]+[winfo rooty .]
1955 frame .select_event.radio
1956 frame .select_event.row2
1959 set radio .select_event.radio
1960 # set default choice
1961 set event_choice [lindex [lindex $event_ids_info 0] 0]
1963 # note: the variables in a -variable statement MUST be global
1964 foreach event_id $event_ids_info {
1965 set win_name [filter_bad_chars [lindex $event_id 0]]
1966 radiobutton $radio.radio$win_name -text $event_id -relief flat -anchor w \
1967 -variable event_choice -value [lindex $event_id 0]
1968 pack $radio.radio$win_name -fill x -expand 1
1971 button .select_event.row2.ok -text "ok" -command "destroy .select_event "
1972 button .select_event.row2.cancel -text "cancel" -command "set exit_now 1 ; destroy .select_event"
1973# if {$which_time=="first_time"} {
1974# button .select_event.row2.openfile \
1975# -text "open file" -command "set open_file 1;destroy .select_event"
1976# pack .select_event.row2.openfile -side right
1980 pack .select_event.row2 -side bottom
1981 pack .select_event.row2.ok -side left
1982 pack .select_event.row2.cancel -side right
1985 # !! The next command forces the script to halt until the .select_event
1986 # dialog box has been destroyed. This is the only way to get a 'top down'
1989 tkwait window .select_event
2004#===================================================================
2005# EMPTY THE ITEM LIST DESTROY EXISTING VECTORS
2006#===================================================================
2008proc clean_list_and_vectors_and_widgets { } {
2009 global item_fname item_fields item_pattern item_equation
2010 global item_color item_max item_min item_list
2013 $select_men delete 1 [llength $item_list] ;# remove pull down menu's
2015# GJH Nov-01. This doesnt seem to work. I dont get the scope of vectors
2016 foreach item $item_list {
2019 global V_y_plot_$item
2020 if {[array exist V_x_$item]} {vector destroy V_x_$item}
2021 if {[array exist V_y_$item]} {vector destroy V_y_$item}
2022 if {[array exist V_y_plot_$item]} {vector destroy V_y_plot_$item}
2027 if {[array exist item_fname]} {unset item_fname}
2028 if {[array exist item_fields]} {unset item_fields}
2029 if {[array exist item_pattern]} {unset item_pattern}
2030 if {[array exist item_equation]} {unset item_equation}
2031 if {[array exist item_color]} {unset item_color}
2032 if {[array exist item_max]} {unset item_max}
2033 if {[array exist item_min]} {unset item_min}
2042#===================================================================
2043# READ THE MHIST -l OUTPUT TO FIND EVID's, VARIABLE NAMES
2044#===================================================================
2046proc get_mhist_list { } {
2047 global event_ids_info ;#mhist event ID and name
2048 global event_var ;#varialbe name
2049 global debug_code ;#general code debug
2050 global file_pref ; #/tmp tmp file prefix
2051 global file_path ;# path to dir containing history files.
2053# erase the previous list
2055 set event_ids_info ""
2056 if {[array exist event_var]} {unset event_var}
2058 set file_hndl [open "/tmp/${file_pref}mhist" r]
2060 while {! [eof $file_hndl]} {
2061 gets $file_hndl string
2063# check for a couple of commom errors:
2064 if {[string first "cannot find recent history file" $string ] !=-1} {
2065 tk_messageBox -message "mhist output: \n $string \n\n\
2066 Possible cause: you are not in the current working directory.\n\
2067 Set directory using Mhist-->Set History Path"
2071# look for a couple of things: ID: give event iD number
2072# x: gives some of the possible variables.
2073 if {[string first "Event ID" $string ] !=-1 } {
2074 # ok, found an event ID: read the id, name
2075 # look for ID and the ':'
2076 set pos1 [string first "ID" $string]
2077 set pos2 [string first ":" $string]
2078 set evid [string range $string [expr $pos1 +2 ] [expr $pos2 -1] ]
2079 set evid [string trim $evid]
2080 set evnam [string range $string [expr $pos2 +1] [string length $string]]
2081 set evnam [string trim $evnam]
2082 lappend event_ids_info "$evid $evnam"
2086 while {![eof $file_hndl] && [llength $string ] == 0 } {
2087 gets $file_hndl string
2089 # read the variables
2090 while {![eof $file_hndl] && [llength $string] != 0 } {
2091 # skip midas error messages:
2092 while {[string first "midas.c" $string ] !=-1 } {
2093 gets $file_hndl string
2095 # take everything beyond the first :
2096 set pos [string first ":" $string]
2097 set nam [string range $string [expr $pos +1 ] end ]
2098 set nam [string trim $nam]
2099 if {[string length $nam] !=0} {
2100 lappend event_var($evid) $nam
2102 gets $file_hndl string
2112#=========================================================================
2113# REMOVE SPACES, UNDERSCORES, OTHER NON ALPHANUMERIC CHARACTERS
2114#=========================================================================
2116proc filter_bad_chars {word} {
2117 set word [string tolower $word]
2118 regsub -all "\\." $word "_" word ;# eliminate '.' characters
2119 regsub -all "\\+" $word "p" word ;# eliminate '+' characters
2120 regsub -all "\\-" $word "_" word ;# eliminate '-' characters
2121 regsub -all {\[} $word "_" word ;# eliminate '[' characters
2122 regsub -all {\]} $word "_" word ;# eliminate ']' characters
2123 regsub -all " " $word "_" word ;# eliminate ' ' characters
2124 regsub -all "#" $word "_nr_" word ;# eliminate '#' characters
2125 regsub -all "%" $word "_" word ;# eliminate '%' characters
2130#==========================================================================
2131# GENERATE NEW COLORS FOR GRAPHS
2132#==========================================================================
2133proc get_new_color { } {
2135 global color_pointer
2136 global max_color_number
2138 set color {SpringGreen1 navy purple orange red cyan DarkGreen blue3 brown green goldenrod \
2139 orange maroon DarkSlateGrey purple blue4 LimeGreen sienna}
2141 set max_color_number 17
2145 if {$color_pointer > $max_color_number} {set color_pointer 0}
2147 return [lindex $color $color_pointer]
2151proc set_main_y_scale {new_ratio} {
2152 # this routine changes the effective y-scale from a the
2153 # standard value of 0-1 to a bigger range using the
2154 # value extracted rom the RHS slider
2158 if { $new_ratio<= 2 } {
2163 set mmin [expr -1.* $new_ratio]
2166 $strip_chart yaxis configure -min $mmin -max $mmax
2172#===========================================================================
2174#===========================================================================
2175proc set_file_path { } {
2177 global file_path ;# path to actual history files
2181 # get current working dir as first guess
2182 if {$file_path==""} {catch "exec pwd" file_path}
2185 toplevel .inputbox ;# make a seperate window for this
2186# put new window at (x,y) of root window:
2187 wm geometry .inputbox +[winfo rootx .]+[winfo rooty .]
2189 frame .inputbox.row1
2190 frame .inputbox.row3
2192 grid .inputbox.row1 -row 1
2193 grid .inputbox.row3 -row 3
2195 label .inputbox.row1.startlab -text "Path to history files: " -height 2
2196 entry .inputbox.row1.start -textvariable file_path -width 40 -font $tit_font
2197 pack .inputbox.row1.start -side right
2198 pack .inputbox.row1.startlab -side left
2200 # create a button which, when clicked, will read the box, then destroy the box
2201 button .inputbox.row3.ok -text "ok" -command {
2202 .inputbox.row1.start get ;# gets read into var.
2205 button .inputbox.row3.cancel -text "cancel" -command {
2209 pack .inputbox.row3.ok -side left
2210 pack .inputbox.row3.cancel -side left
2211 tkwait window .inputbox ;# wait until its been destroyed
2214 if {$debug_code} { puts "Setting file path to $file_path"}
2221#===========================================================================
2223#===========================================================================
2226 toplevel .info ; # create a new window
2227 # put a an <ok> button on it:
2228 button .info.ok -text "OK" -command {destroy .info ; return}
2229 pack .info.ok -side bottom
2231 # now create the text widget
2232 # text .info.text -height 25 -width 65
2233 # pack .info.text -side top
2235 # put the text in the window:
2236 # .info.text insert end " \
2238 # use a message window instead of a text window - simpler
2239 message .info.mess -width 6.5i -text \
2240 "Introduction: Stripchart can:\n\n\
2241 1. plot any data in the\
2242 midas database. It uses mchart, (a midas utility) to actually\
2243 extract the data from odb\n\n\
2244 2. view the data stored by mhist, the MIDAS history program.\n\n\n \
2245 This program should live in the ~/bin directory. To start it \
2246 type\n stripchart <name_of_conf_file> or just\n stripchart \n to look\
2247 at data in the history files\n\n \
2248 The configuration files \
2249 are generated by mchart (eg. target.conf, chvi.conf) and \
2250 are in the same format as that understood by gnome \
2252 Example: to see the CHAOS target info type: \n \
2253 mchart -q /equipment/target/variables -f target.conf\n\
2254 and then start\n stripchart target.conf\n or just type \n \
2255 mchart -q /equipment/target/variables -g -f target.conf \n \
2256 \n and stripchart is invoked automatically \n\n\n\
2257 Note that all overlayed graphs are scaled using the max/min values \
2258 defined in the .conf file to fit between 0 and 1. Hence the \
2259 unlabelled y-scale on the main window.\n\
2260 To see a particular data set in its normal, unscaled \
2261 units, use 'view full graph' and select the line or just click \
2262 with the mouse on a point close to the line of interest. \n\n \
2263 Note that the single graphs can be zoomed by dragging the mouse, \
2264 auto-scaled, or 'best' scaled. Hardcopy is available in ps, jpg, gif \
2265 or png format and goes to a file.\n\n\
2266 To use the history function, click on the mhist button. You must be \
2267 in the directory containing the .hst files. You will\
2268 then be asked to select the event number and data words, as well as the\
2269 history duration and interval\
2271 The tcl interpreter bltwish must be in your system.\n
2272 G.J. Hofman gertjan@triumf.ca \n \
2276 pack .info.mess -side bottom
2285#======================================================================================
2287#======================================================================================
2289# set a few parameters
2293set tit_font "-*-helvetica-bold-r-normal-*-13-180-*-*-*-*-*-*"
2295# define the default scrolling time period
2296set time_limit [expr 60*60] ;# in seconds 5 min default.
2298# default y-scaling values for the pop-up windows
2302set last_rescale_time [clock seconds] ;# last time we checked the scaling
2303 # of the pop up windows
2308set doing_mhist 0 ;# data from mhist OR mchart conf file
2314#new:search for latest mhist
2318# get the file name of the .conf files. Command line parsing
2319set arguse 0 ;# no arguments used up by options
2321set display_item_cnt 0 ;# when showing 5 detailed at same time, the pointer.
2323set fix_y_scale 0 ;# whether or not mouse zoom changes y-scale
2325# no option = doing mhistory
2326# last option parameter = .conf file name
2331 for {set i 0} {$i < $argc } {incr i} {
2332 switch -glob -- [lindex $argv $i] {
2333 "-h" {puts "Usage: stripchart <-options> <config-file>\n\
2334 -mhist (look at history file -default)\n\
2335 -dmhist debug mhist \n\
2336 -debug debug stripchart\n\
2337 config_file: see mchart"
2339 "-mhist" { set doing_mhist 1 ; incr arguse}
2340 "-dmhist" { set debug mhist ; incr arguse}
2341 "-debug" { set debug_code 1 ; incr arguse}
2344 if {$arguse < $argc} {
2345 set conf_fname [lindex $argv [expr $argc -1] ]
2353 puts "Debug: doing mhist "
2355 puts "Debug: doing mchart "
2361 if {![file exists $conf_fname]} {
2362 tk_messageBox -message "Error: conf file $conf_fname not found_!" -type ok
2365 # read in the .conf file and parse:
2366 read_conf_file $conf_fname
2371frame .main -background beige ;# define name of main window.
2372frame .main.toprow -relief ridge -bd 3 ;# for the buttons
2373frame .main.middle -relief ridge -bd 3 ;# for the graph
2374frame .main.botrow ;# unused for now
2376wm title . "midas stripchart: $equip_name (GJH v.2.2)" ;# configure the FVWM window
2377wm iconname . "StripC"
2379set strip_chart .main.middle.strip_chart
2381#graph $strip_chart -background goldenrod -title "" ;# no title on the graph.
2382graph $strip_chart -background "#02a2fe" -title "" ;# no title on the graph.
2384# standard size is 5.5ix 2.0i
2385$strip_chart configure -width 6.5i -height 2.5i -font $tit_font
2387#$strip_chart marker create bitmap -under yes -coords { .2 .7} -bitmap @midas.xbm
2390# configure the x-axis to plot Clock time instead of plain numbers
2391$strip_chart xaxis configure -loose 0 -title "" \
2392 -command "my_clock_format %H:%M" -tickfont $tit_font -titlefont $tit_font
2394# fix the yaxis scale
2395$strip_chart yaxis configure -min 0 -max 1 \
2396 -tickfont $tit_font -titlefont $tit_font -showticks 0
2398# switch on cross hairs
2399#Blt_Crosshairs $strip_chart ;# what is this comand ???
2400# bind the mouse click to the item search routine and pass
2401# window name, x and y coordinate
2402bind $strip_chart <B1-ButtonRelease> "mouse_find_item %W %x %y"
2404# create an exit button. The -bd 0 mean a tight fit of text - no border
2405button .main.toprow.exit -text "exit" -command {nice_exit} -relief flat -underline 0
2406pack .main.toprow.exit -side left
2409# create an exit button
2410button .main.toprow.help -text "help" -command {help_menu} -relief flat -underline 0 -bd 0
2411pack .main.toprow.help -side left
2414# menu for selecting of individual items = make a 'menubutton'
2415set select_but [menubutton .main.toprow.select -text "detail-single" \
2416 -menu .main.toprow.select.mnu -relief flat -underline 0 -bd 0 ]
2417set select_men [menu $select_but.mnu]
2419pack $select_but -side left -fill x
2422# Nov 201- new way of showing detail graphs:
2423button .main.toprow.show_all -text "detail-all" -command {show_all_full_scale} \
2424 -relief flat -underline 0 -bd 0
2425pack .main.toprow.show_all -side left
2429# create an *new* scroll time selection.
2431menubutton .main.toprow.scrollt -text "scroll time" -menu .main.toprow.scrollt.mnu \
2432 -relief flat -underline 0 -bd 0
2433menu .main.toprow.scrollt.mnu
2434.main.toprow.scrollt.mnu add radiobutton -label "100 s" -variable time_limit \
2436.main.toprow.scrollt.mnu add radiobutton -label "5 mins" -variable time_limit \
2438.main.toprow.scrollt.mnu add radiobutton -label "30 mins" -variable time_limit \
2440.main.toprow.scrollt.mnu add radiobutton -label "1 hour" -variable time_limit \
2442.main.toprow.scrollt.mnu add radiobutton -label "5 hour" -variable time_limit \
2443 -value [expr 5*60*60]
2444.main.toprow.scrollt.mnu add radiobutton -label "10 hours" -variable time_limit \
2445 -value [expr 10*60*60]
2446.main.toprow.scrollt.mnu add radiobutton -label "24 hours" -variable time_limit \
2447 -value [expr 24*60*60]
2448pack .main.toprow.scrollt -side left -fill x
2451# old mhist button, now replaced by a pull down meni
2452#button .main.toprow.hist -text "mhist" -command {read_mhist} \
2453# -relief flat -underline 0 -bd 0
2454#pack .main.toprow.hist -side left
2456set mhist_but [menubutton .main.toprow.mhist -text "mhist" \
2457 -menu .main.toprow.mhist.mnu -relief flat -underline 0 -bd 0]
2458set mhist_men [menu $mhist_but.mnu]
2459pack $mhist_but -side left -fill x
2460$mhist_men add command -command "read_present_mhist" -label "Today's MHIST"
2461$mhist_men add command -command "read_mhist_file 1" -label "Open old history file"
2462$mhist_men add command -command "read_mhist_file 0" -label "Same file, New event"
2463$mhist_men add command -command "set_file_path" -label "Set history-file path"
2466# create a warning label to show whether we have new data coming in
2467label .main.toprow.update -relief sunken \
2468 -textvariable prev_update_time_formatted -bd 0
2469pack .main.toprow.update -side right
2470label .main.toprow.warning -relief flat -pady 4 \
2471 -text "Update: " -background green -bd 0
2472pack .main.toprow.warning -side right -fill x
2474# pack all the remaining windows: - first pack graph in middle row:
2475# note: its the 'fill both' and 'expand 1' that does the resizing
2476# of the graph when the window size changes.
2478pack $strip_chart -side left -fill both -expand 1 ;# put it in its parent.
2480# then pack middlerow in the .main:
2481pack .main.middle -side top -fill both -expand 1
2482pack .main.toprow -side top -fill x -expand 1
2484#pack .main.botrow -side top -fill both -expand 1 ; # bot row unused
2486pack .main -fill both -expand 1 ;# put it all on the screen
2489# try the slider to change the scale of the main graph
2490# note: the -command automatically appends the value of the slide
2492#scale .main.middle.slide -orient vertical -label "" -variable scale_slider \
2493# -borderwidth 0 -showvalue 0 -width 10 -from 10 -to .1 \
2494# -command "set_main_y_scale"
2495#pack .main.middle.slide -side right -fill y -expand 1
2499# check if we can write to /tmp/ - get a file namw prefix.
2500# catch returns zero if it's ok.
2504# look until we have no error from deletion:
2505while { [catch "exec rm -f /tmp/${file_pref}mhist" error_var] || \
2506 [catch "exec rm -f /tmp/${file_pref}mhist_data" error_var] } {
2512#============================================================================
2513# CODE HERE IS INFINITE LOOP FOR MHIST USAGE
2514#============================================================================
2516# ok, done all the things we can do for both mhist AND normal stripcharting
2517# if we didn't open a .conf file, just sit here and wait:
2519 .main.toprow.warning configure -text "mhist " -background cyan
2522 $strip_chart configure -background "#02a2fe"
2523 wm title . "midas stripchart: $equip_name (GJH v.2.0)"
2530# ===============================================================================
2531# CODE BELOW FOR ONLINE STRIPCHARTING ONLY
2532# ===============================================================================
2534# remove the mist button - dont need it for mchar applications
2538# create the pull down item menu. Also align the text string
2540foreach item $item_list {
2541 set item_length [string length $item]
2542 if {$item_length > 13} {set item_length 13}
2543 set menu_string "$item [string range $blank_string 1 [expr 13 - $item_length
2545 append menu_string $item_color($item)
2546 $select_men add command -command "select_graph $item" -label $menu_string
2550# ok, finally, create vectors associated with the data.
2551# create also the graph elements:
2553foreach item $item_list {
2554 if {! [$strip_chart element exists line_$item]} {
2555 $strip_chart element create line_$item
2557 tk_messageBox -message "Error(online): line $item already exist - skipped "
2560 $strip_chart element configure line_$item -label "" -color $item_color($item) -symbol ""
2561 vector create V_y_$item ;# for storing raw data
2562 vector create V_y_plot_$item ;# 'scaled' vector for plotting
2563 vector create V_x_$item ;# time vector.
2564 # now hot-link it to the new graph line
2565 $strip_chart element configure line_$item -xdata V_x_$item -ydata V_y_plot_$item
2570# for now I am assuming all data values are read from the SAME file.
2572set data_fname $item_fname([lindex $item_list 0]) ;# just grab the first filename
2575# main plotting loop:
2577set prev_update_time 0 ;# last time the data file was written
2583# check if the file exist and when it was last written
2585 if {![file exists $data_fname]} {
2586 show_message "Error: data file $data_fname not found !"
2587 .main.toprow.warning configure -text "No Data File" -background red
2588 vwait message_done ;# wait until message ok button was hit.
2589 # go into loop, waiting for file:
2590 while {![file exists $data_fname]} {
2595 # check the last modification time of the file:
2596 while { [file mtime $data_fname]== $prev_update_time} {
2599 set time_passed [expr ( [clock seconds] - [file mtime $data_fname])]
2600 if { $time_passed > 200 } {
2601 .main.toprow.warning configure -text "No Data" -background red
2607# ok, we have a new file:
2608 .main.toprow.warning configure -text "Update: " -background green
2610 set prev_update_time [file mtime $data_fname]
2611# for output to screen, format the time for humans:
2612 set prev_update_time_formatted [clock format $prev_update_time -format "%H:%M:%S"]
2614 set file_hndl [open $data_fname r]
2617 # loop over all lines in the file
2618 while {! [eof $file_hndl]} {
2620 gets $file_hndl string
2622 # for some reason, the last line is an empty string. Not sure why
2623 # skip empty strings
2624 if {[string length $string]==0} {
2628 set item_string [lindex $string 0]
2630 set item_string [string tolower $item_string]
2631 # remove underscores etc.
2632 set item_string [filter_bad_chars $item_string]
2634 # loop over all known keyword and compare to file.
2637 foreach item $item_list {
2638 if { $item==$item_string} {
2640 set new_data [expr 1.0 *[lindex $string 1]]
2641 set vec_name V_x_$item
2642 set ${vec_name}(++end) $prev_update_time
2643 set vec_name V_y_$item
2644 set ${vec_name}(++end) $new_data
2646 # now scale the vector to fit on the graph.
2647 set plot_vec_name V_y_plot_$item
2649 [expr " ($new_data - $item_min($item)) / ($item_max($item)-$item_min($item)) " \
2651 # note I add a small offset... just so that lines dont overlap each other
2652 set ${plot_vec_name}(++end) $norm_data
2661 # take care of the scrolling:
2662 # I do some tricky double de-referencing here. I need to access the
2663 # vector but I only have the name of the vector. So the inner 'set'
2664 # returns the name of the vector. I then concatenate (0) and
2665 # finally get the actual value stored in the vector
2668 foreach item $item_list {
2669 set oldest_time [ set V_x_[set item](0)]
2670 set newest_time [ set V_x_[set item](end)]
2672# puts "data are now [set V_y_[set item](:)]"
2674 if { [expr ( $newest_time - $oldest_time)] > $time_limit } {
2677 V_y_plot_$item delete 0
2682 # also check if we you re-evaluate the scaling on the individual plots
2683 # say at every 300 s.
2684 set time_now [clock seconds]
2685 if { [expr $time_now - $last_rescale_time ] > 200} {
2686 foreach item $item_list {
2687 if [winfo exists .fullscale$item ] {
2688 scale_single_window Rescale $item 1
2690 if [winfo exist .fullscale_main.fullscale$item] {
2691 scale_single_window Rescale $item 2
2694 set last_rescale_time $time_now
2706#=======================================================================================
2707#====================== END OF CODE ====================================================
2708#=======================================================================================