source: trunk/MultiChannelUSB/UserInterface.tcl@ 169

Last change on this file since 169 was 169, checked in by demin, 12 years ago

add region of interest to histogram view

File size: 69.6 KB
Line 
1package require XOTcl
2
3package require BLT
4package require swt
5package require usb
6
7package require zlib
8
9wm minsize . 990 680
10
11image create bitmap leftarrow -data "
12#define leftarrow_width 5\n
13#define leftarrow_height 5\n
14static unsigned char leftarrow_bits\[\] = {\n
150x10, 0x1C, 0x1F, 0x1C, 0x10};"
16image create bitmap rightarrow -data "
17#define rightarrow_width 5\n
18#define rightarrow_height 5\n
19static unsigned char rightarrow_bits\[\] = {\n
200x01, 0x07, 0x1F, 0x07, 0x01};"
21
22namespace eval ::mca {
23 namespace import ::xotcl::*
24
25 namespace import ::blt::vector
26 namespace import ::blt::graph
27 namespace import ::blt::tabnotebook
28
29# -------------------------------------------------------------------------
30
31 variable oscCodes
32 array set oscCodes {
33 1 {Channel 1}
34 2 {Channel 2}
35 3 {Channel 3}
36 4 {Channel 4}
37 5 {Channel 5}
38 6 {Trigger}
39 }
40
41# -------------------------------------------------------------------------
42
43 variable adcCodes
44 array set adcCodes {
45 1 {ADC 1}
46 2 {ADC 2}
47 3 {ADC 3}
48 }
49
50# -------------------------------------------------------------------------
51
52 variable inpCodes
53 array set inpCodes {
54 0 {raw data}
55 1 {filtered}
56 2 {amplitude}
57 3 {amp flag}
58 }
59
60# -------------------------------------------------------------------------
61
62 proc validate {max size value} {
63 if {![regexp {^[0-9]*$} $value]} {
64 return 0
65 } elseif {[regexp {^0[0-9]+$} $value]} {
66 return 0
67 } elseif {$value > $max} {
68 return 0
69 } elseif {[string length $value] > $size} {
70 return 0
71 } else {
72 return 1
73 }
74 }
75
76# -------------------------------------------------------------------------
77
78 proc doublevalidate {max value} {
79 if {![regexp {^[0-9]{0,2}\.?[0-9]{0,3}$} $value]} {
80 return 0
81 } elseif {[regexp {^0[0-9]+$} $value]} {
82 return 0
83 } elseif {$value > $max} {
84 return 0
85 } else {
86 return 1
87 }
88 }
89
90# -------------------------------------------------------------------------
91
92 proc legendLabel {master row key title} {
93 label ${master}.${key}_label -anchor w -text ${title}
94 label ${master}.${key}_value -width 10 -anchor e -text {}
95
96 grid ${master}.${key}_label -row ${row} -column 1 -sticky w
97 grid ${master}.${key}_value -row ${row} -column 2 -sticky ew
98 }
99
100# -------------------------------------------------------------------------
101
102 proc legendButton {master row key title var bg {fg black}} {
103 checkbutton ${master}.${key}_check -variable $var
104 label ${master}.${key}_label -anchor w -text ${title} -bg ${bg} -fg $fg
105 label ${master}.${key}_value -width 10 -anchor e -text {} -bg ${bg} -fg $fg
106
107 grid ${master}.${key}_check -row ${row} -column 0 -sticky w
108 grid ${master}.${key}_label -row ${row} -column 1 -sticky w
109 grid ${master}.${key}_value -row ${row} -column 2 -sticky ew
110 }
111
112# -------------------------------------------------------------------------
113
114 Class UsbController
115
116# -------------------------------------------------------------------------
117
118 UsbController instproc usbConnect {} {
119 my instvar handle
120
121 puts usbConnect
122
123 if {[my exists handle]} {
124 $handle disconnect
125 unset handle
126 }
127if {0} {
128 while {[catch {usb::connect 0x09FB 0x6001 1 1 0} result]} {
129 set answer [tk_messageBox -icon error -type retrycancel \
130 -message {Cannot access USB device} -detail $result]
131# puts $result
132 if {[string equal $answer cancel]} exit
133 }
134
135 set handle $result
136
137}
138 }
139
140# -------------------------------------------------------------------------
141
142 UsbController instproc usbHandle {} {
143 my instvar handle
144
145 if {[my exists handle]} {
146 return $handle
147 } else {
148 my usbConnect
149 }
150 }
151
152# -------------------------------------------------------------------------
153
154 UsbController instproc usbCmd {command} {
155 set code [catch {[my usbHandle] writeRaw [usb::convert $command]} result]
156 switch -- $code {
157 1 {
158# puts $result
159 my usbConnect
160 }
161 }
162
163 }
164
165# -------------------------------------------------------------------------
166
167 UsbController instproc usbCmdReadRaw {command size data} {
168 my usbCmd $command
169
170 set code [catch {[my usbHandle] readRaw $size} result]
171 switch -- $code {
172 0 {
173 set $data $result
174 }
175 1 {
176# puts $result
177 my usbConnect
178 }
179 5 {
180# puts Busy
181 }
182 }
183 }
184
185# -------------------------------------------------------------------------
186
187 UsbController instproc usbCmdReadRaw {command size data} {
188 my usbCmd $command
189
190 set code [catch {[my usbHandle] readRaw $size} result]
191 switch -- $code {
192 0 {
193 set $data $result
194 }
195 1 {
196# puts $result
197 my usbConnect
198 }
199 5 {
200# puts Busy
201 }
202 }
203 }
204
205# -------------------------------------------------------------------------
206
207 UsbController instproc usbCmdReadHex {command width size data} {
208 my usbCmd $command
209
210 set code [catch {[my usbHandle] readHex $width $size} result]
211 switch -- $code {
212 0 {
213 set $data $result
214 }
215 1 {
216# puts $result
217 my usbConnect
218 }
219 5 {
220# puts Busy
221 }
222 }
223 }
224
225# -------------------------------------------------------------------------
226
227 Class MuxDisplay -parameter {
228 {master}
229 {controller}
230 }
231
232# -------------------------------------------------------------------------
233
234 MuxDisplay instproc init {} {
235
236 my setup
237
238 next
239 }
240
241# -------------------------------------------------------------------------
242
243 MuxDisplay instproc destroy {} {
244 next
245 }
246
247# -------------------------------------------------------------------------
248
249 MuxDisplay instproc start {} {
250 my instvar config chan_val hstmux
251
252 set chan_val(1) 0
253 set chan_val(2) 0
254 set chan_val(3) 0
255 set chan_val(4) 0
256 set chan_val(5) 0
257 set chan_val(6) 0
258
259 set hstmux(1) 0
260 set hstmux(2) 0
261 set hstmux(3) 0
262
263 trace add variable [myvar chan_val] write [myproc chan_val_update]
264 trace add variable [myvar polar] write [myproc polar_update]
265 trace add variable [myvar hstmux] write [myproc hstmux_update]
266
267 $config(1).chan_1_1 select
268 $config(2).chan_1_2 select
269 $config(3).chan_1_3 select
270 $config(4).chan_1_1 select
271 $config(5).chan_3_1 select
272 $config(6).chan_3_1 select
273
274 $config(7).hstmux_1_1 select
275 $config(8).hstmux_2_2 select
276 $config(9).hstmux_3_1 select
277
278 for {set i 1} {$i <= 3} {incr i} {
279 $config(10).polar_$i select
280 }
281 }
282
283# -------------------------------------------------------------------------
284
285 MuxDisplay instproc setup {} {
286 variable oscCodes
287 variable adcCodes
288 variable inpCodes
289 my instvar master
290 my instvar config
291
292 set size [array size inpCodes]
293 set oscList [array get oscCodes]
294 set adcList [array get adcCodes]
295 set inpList [array get inpCodes]
296
297 foreach {osc title} $oscList {
298 set config($osc) [labelframe ${master}.mux_$osc -borderwidth 1 -relief sunken -text $title -font {-weight bold}]
299
300 foreach {ch dummy} $adcList {
301 label $config($osc).chan_${ch} -text "#$ch "
302 grid $config($osc).chan_${ch} -row 0 -column $ch -sticky w
303 }
304 foreach {code input} $inpList {
305 set row [expr {$code + 1}]
306 set last 0
307 foreach {ch dummy} $adcList {
308 set value [expr {$size * ($ch - 1) + $code}]
309 radiobutton $config($osc).chan_${code}_${ch} -variable [myvar chan_val($osc)] -value ${value}
310 grid $config($osc).chan_${code}_${ch} -row ${row} -column $ch -sticky w
311 set last $ch
312 }
313 $config($osc).chan_${code}_${last} configure -text $input
314 }
315 set column [expr {($osc - 1) % 3}]
316 set row [expr {($osc - 1) / 3 + 1}]
317 grid $config($osc) -row $row -column $column -sticky news -padx 10 -pady 10
318 }
319
320 set config(7) [labelframe ${master}.mux_7 -borderwidth 1 -relief sunken -text {Spectrum histogram 1} -font {-weight bold}]
321 set config(8) [labelframe ${master}.mux_8 -borderwidth 1 -relief sunken -text {Spectrum histogram 2} -font {-weight bold}]
322 set config(9) [labelframe ${master}.mux_9 -borderwidth 1 -relief sunken -text {Rate histogram} -font {-weight bold}]
323
324 set config(10) [labelframe ${master}.mux_10 -borderwidth 1 -relief sunken -text {Polarity inversion} -font {-weight bold}]
325
326 for {set i 1} {$i <= 3} {incr i} {
327 set value [expr {$i - 1}]
328
329 radiobutton $config(7).hstmux_1_$i -text "ADC $i" -variable [myvar hstmux(1)] -value $value
330 grid ${config(7)}.hstmux_1_$i
331
332 radiobutton $config(8).hstmux_2_$i -text "ADC $i" -variable [myvar hstmux(2)] -value $value
333 grid ${config(8)}.hstmux_2_$i
334
335 radiobutton $config(9).hstmux_3_$i -text "ADC $i" -variable [myvar hstmux(3)] -value $value
336 grid ${config(9)}.hstmux_3_$i
337
338 checkbutton $config(10).polar_$i -text "ADC $i" -variable [myvar polar($i)]
339 grid ${config(10)}.polar_$i
340 }
341 grid $config(7) -row 3 -column 0 -sticky news -padx 10 -pady 30
342 grid $config(8) -row 3 -column 1 -sticky news -padx 10 -pady 30
343 grid $config(9) -row 3 -column 2 -sticky news -padx 10 -pady 30
344
345 grid $config(10) -row 4 -column 0 -sticky news -padx 10 -pady 10
346
347 grid columnconfigure ${master} 0 -weight 1
348 grid columnconfigure ${master} 1 -weight 1
349 grid columnconfigure ${master} 2 -weight 1
350
351 grid rowconfigure ${master} 0 -weight 1
352 grid rowconfigure ${master} 1 -weight 0
353 grid rowconfigure ${master} 2 -weight 0
354 grid rowconfigure ${master} 3 -weight 0
355 grid rowconfigure ${master} 4 -weight 0
356 grid rowconfigure ${master} 5 -weight 1
357
358 }
359
360
361# ------------------------------------------------------------------------
362
363 MuxDisplay instproc chan_val_update args {
364 my instvar controller chan_val
365
366 set byte1 [format {%02x%02x} $chan_val(2) $chan_val(1)]
367 set byte2 [format {%02x%02x} $chan_val(4) $chan_val(3)]
368 set byte3 [format {%02x%02x} $chan_val(6) $chan_val(5)]
369
370 $controller usbCmd 000200020004${byte1}000200030004${byte2}000200040004${byte3}
371 }
372
373# -------------------------------------------------------------------------
374
375 MuxDisplay instproc polar_update args {
376 my instvar controller polar
377
378 set value [format {%x%x%x} $polar(3) $polar(2) $polar(1)]
379
380 $controller usbCmd 0002000100040${value}
381 }
382
383# -------------------------------------------------------------------------
384
385 MuxDisplay instproc hstmux_update args {
386 my instvar controller hstmux
387
388 set value [format {%x%x%x} $hstmux(3) $hstmux(2) $hstmux(1)]
389
390 $controller usbCmd 0002000600040${value}
391 }
392
393# -------------------------------------------------------------------------
394
395 Class HstDisplay -parameter {
396 {number}
397 {master}
398 {controller}
399 }
400
401# -------------------------------------------------------------------------
402
403 HstDisplay instproc init {} {
404
405 my set data {}
406
407 vector create [myvar xvec](4096)
408 vector create [myvar yvec](4096)
409
410 # fill one vector for the x axis with 4096 points
411 [myvar xvec] seq -0.5 4095.5
412
413 my setup
414
415 next
416 }
417
418# -------------------------------------------------------------------------
419
420 HstDisplay instproc destroy {} {
421 next
422 }
423
424# -------------------------------------------------------------------------
425
426 HstDisplay instproc start {} {
427 my instvar config
428
429 trace add variable [myvar data] write [myproc data_update]
430 trace add variable [myvar cntr_val] write [myproc cntr_val_update]
431 trace add variable [myvar rate_val] write [myproc rate_val_update]
432
433 trace add variable [myvar axis] write [myproc axis_update]
434 trace add variable [myvar thrs] write [myproc thrs_update]
435 trace add variable [myvar thrs_val] write [myproc thrs_update]
436
437 ${config}.axis_check select
438
439 ${config}.thrs_check select
440 ${config}.thrs_field set 25
441
442 my set xmin_val 0
443 my set xmax_val 4095
444
445 trace add variable [myvar xmin_val] write [myproc xmin_val_update]
446 trace add variable [myvar xmax_val] write [myproc xmax_val_update]
447
448 my stat_update
449
450 set cntr_tmp 1200000000
451 my set cntr_val $cntr_tmp
452 my set cntr_bak $cntr_tmp
453 my set cntr_old $cntr_tmp
454 my set yvec_bak 0.0
455 my set yvec_old 0.0
456
457 my set rate_val(inst) 0.0
458 my set rate_val(mean) 0.0
459
460 ${config}.chan_frame.entr_value configure -text 0.0
461
462 ${config}.chan_frame.axisy_value configure -text 0.0
463 ${config}.chan_frame.axisx_value configure -text 0.0
464
465 ${config}.stat_frame.tot_value configure -text 0.0
466 ${config}.stat_frame.bkg_value configure -text 0.0
467
468# my cntr_reset
469 }
470
471# -------------------------------------------------------------------------
472
473 HstDisplay instproc setup {} {
474 my instvar number master
475 my instvar xvec yvec graph
476 my instvar config thrs thrs_val
477 my instvar cntr_h cntr_m cntr_s
478
479 # create a graph widget and show a grid
480 set graph [graph ${master}.graph -height 250 -leftmargin 80]
481 $graph crosshairs configure -hide no -linewidth 1 -color darkblue -dashes {2 2}
482 $graph grid configure -hide no
483 $graph legend configure -hide yes
484
485 $graph marker create line -name xmin -coords "0 -Inf 0 Inf" -linewidth 2 -outline red
486 $graph marker create line -name xmax -coords "4095 -Inf 4095 Inf" -linewidth 2 -outline red
487 $graph marker bind xmin <Enter> [list [self] marker_enter xmin]
488 $graph marker bind xmin <Leave> [list [self] marker_leave xmin]
489 $graph marker bind xmax <Enter> [list [self] marker_enter xmax]
490 $graph marker bind xmax <Leave> [list [self] marker_leave xmax]
491
492 set config [frame ${master}.config -width 170]
493
494 checkbutton ${config}.axis_check -text {log scale} -variable [myvar axis]
495
496 frame ${config}.spc1 -width 170 -height 20
497
498 frame ${config}.rate_frame -borderwidth 0 -width 170
499 legendLabel ${config}.rate_frame 0 inst {Inst. rate, 1/s}
500 legendLabel ${config}.rate_frame 1 mean {Avg. rate, 1/s}
501
502 frame ${config}.spc2 -width 170 -height 10
503
504 frame ${config}.chan_frame -borderwidth 0 -width 170
505 legendLabel ${config}.chan_frame 0 entr {Total entries}
506 frame ${config}.chan_frame.spc1 -height 10
507 grid ${config}.chan_frame.spc1 -row 1
508 legendLabel ${config}.chan_frame 2 axisy {Bin entries}
509 legendLabel ${config}.chan_frame 3 axisx {Bin number}
510
511 frame ${config}.spc3 -width 170 -height 10
512
513 label ${config}.roi -text {Region of interest}
514 frame ${config}.roi_frame -borderwidth 0 -width 170
515 label ${config}.roi_frame.min_title -anchor w -text {start:}
516 label ${config}.roi_frame.min_value -width 4 -anchor e -text {}
517 label ${config}.roi_frame.spc1 -width 5 -anchor w -text {}
518 label ${config}.roi_frame.max_title -anchor w -text {end:}
519 label ${config}.roi_frame.max_value -width 4 -anchor e -text {}
520
521 grid ${config}.roi_frame.min_title ${config}.roi_frame.min_value \
522 ${config}.roi_frame.spc1 ${config}.roi_frame.max_title \
523 ${config}.roi_frame.max_value
524
525 frame ${config}.stat_frame -borderwidth 0 -width 17
526
527 legendLabel ${config}.stat_frame 0 tot {total entries}
528 legendLabel ${config}.stat_frame 1 bkg {bkg entries}
529
530 frame ${config}.spc4 -width 170 -height 20
531
532 checkbutton ${config}.thrs_check -text {amplitude threshold} -variable [myvar thrs]
533 spinbox ${config}.thrs_field -from 1 -to 4095 \
534 -increment 5 -width 10 -textvariable [myvar thrs_val] \
535 -validate all -vcmd {::mca::validate 4095 4 %P}
536
537 frame ${config}.spc5 -width 170 -height 20
538
539 label ${config}.cntr -text {time of exposure}
540 frame ${config}.cntr_frame -borderwidth 0 -width 170
541
542 label ${config}.cntr_frame.h -width 3 -anchor w -text {h}
543 entry ${config}.cntr_frame.h_field -width 3 -textvariable [myvar cntr_h] \
544 -validate all -vcmd {::mca::validate 999 3 %P}
545 label ${config}.cntr_frame.m -width 3 -anchor w -text {m}
546 entry ${config}.cntr_frame.m_field -width 3 -textvariable [myvar cntr_m] \
547 -validate all -vcmd {::mca::validate 59 2 %P}
548 label ${config}.cntr_frame.s -width 3 -anchor w -text {s}
549 entry ${config}.cntr_frame.s_field -width 6 -textvariable [myvar cntr_s] \
550 -validate all -vcmd {::mca::doublevalidate 59.999 %P}
551
552 grid ${config}.cntr_frame.h_field ${config}.cntr_frame.h \
553 ${config}.cntr_frame.m_field ${config}.cntr_frame.m ${config}.cntr_frame.s_field ${config}.cntr_frame.s
554
555 frame ${config}.spc6 -width 170 -height 20
556
557 button ${config}.start -text Start \
558 -bg yellow -activebackground yellow -command [myproc cntr_start]
559 button ${config}.reset -text Reset \
560 -bg red -activebackground red -command [myproc cntr_reset]
561
562 frame ${config}.spc7 -width 170 -height 20
563
564 button ${config}.register -text Register \
565 -bg lightblue -activebackground lightblue -command [myproc register]
566
567 frame ${config}.spc8 -width 170 -height 20
568
569 button ${config}.recover -text {Read file} \
570 -bg lightblue -activebackground lightblue -command [myproc recover]
571
572 grid ${config}.axis_check -sticky w
573 grid ${config}.spc1
574 grid ${config}.rate_frame -sticky ew -padx 5
575 grid ${config}.spc2
576 grid ${config}.chan_frame -sticky ew -padx 5
577 grid ${config}.spc3
578 grid ${config}.roi -sticky w -pady 1 -padx 5
579 grid ${config}.roi_frame -sticky ew -padx 5
580 grid ${config}.stat_frame -sticky ew -padx 5
581 grid ${config}.spc4
582 grid ${config}.thrs_check -sticky w
583 grid ${config}.thrs_field -sticky ew -pady 1 -padx 5
584 grid ${config}.spc5
585 grid ${config}.cntr -sticky w -pady 1 -padx 3
586 grid ${config}.cntr_frame -sticky ew -padx 5
587 grid ${config}.spc6
588 grid ${config}.start -sticky ew -pady 3 -padx 5
589 grid ${config}.reset -sticky ew -pady 3 -padx 5
590 grid ${config}.spc7
591 grid ${config}.register -sticky ew -pady 3 -padx 5
592 grid ${config}.spc8
593 grid ${config}.recover -sticky ew -pady 3 -padx 5
594
595 grid ${graph} -row 0 -column 0 -sticky news
596 grid ${config} -row 0 -column 1
597
598 grid rowconfigure ${master} 0 -weight 1
599 grid columnconfigure ${master} 0 -weight 1
600 grid columnconfigure ${master} 1 -weight 0 -minsize 80
601
602 grid columnconfigure ${config}.rate_frame 1 -weight 1
603 grid columnconfigure ${config}.chan_frame 1 -weight 1
604 grid columnconfigure ${config}.stat_frame 1 -weight 1
605
606 my crosshairs $graph
607
608 #bind .graph <Motion> {%W crosshairs configure -position @%x,%y}
609
610 # create one element with data for the x and y axis, no dots
611 $graph element create Spectrum1 -color blue -linewidth 2 -symbol none -smooth step -xdata [myvar xvec] -ydata [myvar yvec]
612 }
613
614# -------------------------------------------------------------------------
615
616 HstDisplay instproc marker_enter {marker} {
617 my instvar config graph
618 $graph configure -cursor hand2
619 $graph crosshairs off
620 blt::RemoveBindTag $graph zoom-$graph
621 $graph marker bind $marker <ButtonPress-1> [list [self] marker_press $marker]
622 $graph marker bind $marker <ButtonRelease-1> [list [self] marker_release $marker]
623 }
624
625# -------------------------------------------------------------------------
626
627 HstDisplay instproc marker_leave {marker} {
628 my instvar config graph
629 $graph configure -cursor crosshair
630 $graph crosshairs on
631 blt::AddBindTag $graph zoom-$graph
632 $graph marker bind $marker <ButtonPress-1> {}
633 $graph marker bind $marker <ButtonRelease-1> {}
634 }
635
636# -------------------------------------------------------------------------
637
638 HstDisplay instproc marker_press {marker} {
639 my instvar config graph
640 $graph marker bind $marker <Motion> [list [self] ${marker}_motion %W %x %y]
641 }
642
643# -------------------------------------------------------------------------
644
645 HstDisplay instproc marker_release {marker} {
646 my instvar config graph
647 $graph marker bind $marker <Motion> {}
648 }
649
650# -------------------------------------------------------------------------
651
652 HstDisplay instproc xmin_motion {W x y} {
653 my instvar config graph xmin_val
654 set index [$graph axis invtransform x $x]
655 set index [::tcl::mathfunc::round $index]
656 if {$index < 0} {
657 set index 0
658 }
659 set xmin_val $index
660 }
661
662# -------------------------------------------------------------------------
663
664 HstDisplay instproc xmax_motion {W x y} {
665 my instvar config graph xmax_val
666 set index [$graph axis invtransform x $x]
667 set index [::tcl::mathfunc::round $index]
668 if {$index > 4095} {
669 set index 4095
670 }
671 set xmax_val $index
672 }
673
674# -------------------------------------------------------------------------
675
676 HstDisplay instproc coor_update {W x y} {
677 my instvar config graph
678
679 $W crosshairs configure -position @${x},${y}
680
681 set index [$W axis invtransform x $x]
682 set index [::tcl::mathfunc::round $index]
683 catch {
684 ${config}.chan_frame.axisy_value configure -text [[myvar yvec] index $index]
685 ${config}.chan_frame.axisx_value configure -text ${index}.0
686 }
687 }
688
689# -------------------------------------------------------------------------
690
691 HstDisplay instproc crosshairs {graph} {
692 set method [myproc coor_update]
693 bind $graph <Motion> [list [self] coor_update %W %x %y]
694 bind $graph <Leave> {
695 %W crosshairs off
696 }
697 bind $graph <Enter> {
698 %W crosshairs on
699 }
700 }
701
702# -------------------------------------------------------------------------
703
704 HstDisplay instproc axis_update args {
705 my instvar axis graph
706 $graph axis configure x -min 0 -max 4096
707 Blt_ZoomStack $graph
708 if {$axis} {
709 $graph axis configure y -min 1 -max 1E10 -logscale yes
710 } else {
711 $graph axis configure y -min {} -max {} -logscale no
712 }
713 }
714
715# -------------------------------------------------------------------------
716
717 HstDisplay instproc thrs_update args {
718 my instvar controller config number thrs thrs_val
719
720 if {[string equal $thrs_val {}]} {
721 set thrs_val 0
722 }
723
724 set val_addr [format %02x [expr {7 + ${number}}]]
725
726 if {$thrs} {
727 ${config}.thrs_field configure -state normal
728 set value [format %03x $thrs_val]
729 } else {
730 ${config}.thrs_field configure -state disabled
731 set value 000
732 }
733
734 $controller usbCmd 000200${val_addr}00040${value}
735 }
736
737# -------------------------------------------------------------------------
738
739 HstDisplay instproc stat_update {} {
740 my instvar config graph xmin_val xmax_val
741 set ymin_val [[myvar yvec] index $xmin_val]
742 set ymax_val [[myvar yvec] index $xmax_val]
743
744 ${config}.roi_frame.min_value configure -text $xmin_val
745 ${config}.roi_frame.max_value configure -text $xmax_val
746
747 ${config}.stat_frame.tot_value configure \
748 -text [usb::integrateBlt [myvar yvec] $xmin_val $xmax_val 0]
749
750 ${config}.stat_frame.bkg_value configure \
751 -text [expr {($xmax_val - $xmin_val + 1) * ($ymin_val + $ymax_val) / 2.0}]
752 }
753# -------------------------------------------------------------------------
754
755 HstDisplay instproc xmin_val_update args {
756 my instvar config graph xmin_val xmax_val
757 if {$xmin_val > 4075} {
758 set xmin_val 4075
759 }
760 if {$xmin_val > $xmax_val - 20} {
761 set xmax_val [expr {$xmin_val + 20}]
762 }
763 $graph marker configure xmin -coords "$xmin_val -Inf $xmin_val Inf"
764 my stat_update
765 }
766
767# -------------------------------------------------------------------------
768
769 HstDisplay instproc xmax_val_update args {
770 my instvar config graph xmin_val xmax_val
771 if {$xmax_val < 20} {
772 set xmax_val 20
773 }
774 if {$xmax_val < $xmin_val + 20} {
775 set xmin_val [expr {$xmax_val - 20}]
776 }
777 $graph marker configure xmax -coords "$xmax_val -Inf $xmax_val Inf"
778 my stat_update
779 }
780
781# -------------------------------------------------------------------------
782
783 HstDisplay instproc rate_val_update {name key op} {
784 my instvar config rate_val
785
786 ${config}.rate_frame.${key}_value configure -text [format {%.2e} $rate_val(${key})]
787 }
788
789# -------------------------------------------------------------------------
790
791 HstDisplay instproc cntr_val_update args {
792 my instvar cntr_val cntr_h cntr_m cntr_s
793
794 set cntr_tmp [expr {${cntr_val}/20000}]
795 set cntr_h [expr {${cntr_tmp}/3600000}]
796 set cntr_m [expr {${cntr_tmp}%3600000/60000}]
797 set cntr_s [expr {${cntr_tmp}%3600000%60000/1000.0}]
798 }
799
800# -------------------------------------------------------------------------
801
802 HstDisplay instproc cntr_setup {} {
803 my instvar controller number cntr_val
804
805 set word0 [format %08x [expr {${cntr_val} & 0xFFFFFFFF}]]
806 set word1 [format %08x [expr {${cntr_val} >> 32}]]
807
808 set prefix [format %x [expr {5 + ${number}}]]
809
810 set command {}
811 append command 0001${prefix}000000200000004[string range $word0 4 7]
812 append command 0001${prefix}000000200010004[string range $word0 0 3]
813 append command 0001${prefix}000000200020004[string range $word1 4 7]
814 append command 0001${prefix}000000200030004[string range $word1 0 3]
815
816 # send counter value
817 $controller usbCmd $command
818
819 # load counter value
820# set val_addr [format %02x [expr {12 + ${number}}]]
821# $controller usbCmd 000200${val_addr}00040001000200${val_addr}00040000
822 }
823
824# -------------------------------------------------------------------------
825
826 HstDisplay instproc cntr_reset {} {
827 my instvar controller config number after_handle
828 my instvar cntr_val cntr_bak cntr_old yvec_bak yvec_old rate_val
829
830 my cntr_stop
831
832 set value [format %04x [expr {1 << (5 + ${number})}]]
833 $controller usbCmd 000200000004${value}0002000000040000
834
835 set cntr_val $cntr_bak
836 my cntr_setup
837
838 set cntr_old $cntr_bak
839 set yvec_bak 0.0
840 set yvec_old 0.0
841
842 set rate_val(inst) 0.0
843 set rate_val(mean) 0.0
844 ${config}.chan_frame.entr_value configure -text 0.0
845
846 my acquire
847
848 my cntr_ready
849 }
850
851# -------------------------------------------------------------------------
852
853 HstDisplay instproc cntr_ready {} {
854 my instvar config cntr_val cntr_bak
855
856 set cntr_val $cntr_bak
857
858 ${config}.start configure -text Start -command [myproc cntr_start]
859 ${config}.reset configure -state active
860
861 ${config}.cntr_frame.h_field configure -state normal
862 ${config}.cntr_frame.m_field configure -state normal
863 ${config}.cntr_frame.s_field configure -state normal
864 }
865
866# -------------------------------------------------------------------------
867
868 HstDisplay instproc cntr_start {} {
869 my instvar config
870 my instvar cntr_h cntr_m cntr_s
871 my instvar cntr_val cntr_bak cntr_old yvec_bak yvec_old
872
873 set h $cntr_h
874 set m $cntr_m
875 set s $cntr_s
876
877 if {[string equal $h {}]} {
878 set h 0
879 }
880 if {[string equal $m {}]} {
881 set m 0
882 }
883 if {[string equal $s {}]} {
884 set s 0
885 }
886
887 set cntr_tmp [expr {${h}*3600000 + ${m}*60000 + ${s}*1000}]
888 set cntr_tmp [expr {entier(20000 * ${cntr_tmp})}]
889
890 if {$cntr_tmp > 0} {
891 ${config}.cntr_frame.h_field configure -state disabled
892 ${config}.cntr_frame.m_field configure -state disabled
893 ${config}.cntr_frame.s_field configure -state disabled
894
895 set cntr_val $cntr_tmp
896 set cntr_bak $cntr_tmp
897 set cntr_old $cntr_tmp
898 set yvec_bak [usb::integrateBlt [myvar yvec] 0 4095 0]
899 set yvec_old $yvec_bak
900
901 my cntr_setup
902
903 my cntr_resume
904 }
905 }
906
907# -------------------------------------------------------------------------
908
909 HstDisplay instproc cntr_pause {} {
910 my instvar config
911
912 my cntr_stop
913
914 ${config}.start configure -text Resume -command [myproc cntr_resume]
915# ${config}.reset configure -state active
916
917 }
918
919# -------------------------------------------------------------------------
920
921 HstDisplay instproc cntr_resume {} {
922 my instvar controller config number auto
923
924 set val_addr [format %02x [expr {13 + ${number}}]]
925
926 ${config}.start configure -text Pause -command [myproc cntr_pause]
927# ${config}.reset configure -state disabled
928
929 $controller usbCmd 000200${val_addr}00040002
930
931 set auto 1
932
933 after 100 [myproc acquire_loop]
934 }
935
936# -------------------------------------------------------------------------
937
938 HstDisplay instproc cntr_stop {} {
939 my instvar controller config number auto
940
941 set val_addr [format %02x [expr {13 + ${number}}]]
942
943 $controller usbCmd 000200${val_addr}00040000
944
945 set auto 0
946 }
947
948# -------------------------------------------------------------------------
949
950 HstDisplay instproc data_update args {
951 my instvar data
952 usb::convertBlt $data 4 [myvar yvec]
953 }
954
955# -------------------------------------------------------------------------
956
957 HstDisplay instproc acquire_loop {} {
958 my instvar cntr_val auto
959
960 my acquire
961
962 if {$cntr_val == 0} {
963 my cntr_stop
964 my cntr_ready
965 } elseif {$auto} {
966 after 1000 [myproc acquire_loop]
967 }
968 }
969
970# -------------------------------------------------------------------------
971
972 HstDisplay instproc acquire {} {
973 my instvar controller config number
974 my instvar cntr_val cntr_bak cntr_old yvec_bak yvec_old rate_val
975
976 set size 4096
977
978 set prefix [format {%x} [expr {2 + ${number}}]]
979
980 set value [format {%08x} [expr {$size * 2}]]
981
982 set command 0001${prefix}000000200000001[string range $value 0 3]0003[string range $value 4 7]00050000
983
984 $controller usbCmdReadRaw $command [expr {$size * 4}] [myvar data]
985 set yvec_new [usb::integrateBlt [myvar yvec] 0 4095 0]
986
987 set prefix [format {%x} [expr {5 + ${number}}]]
988 set command 0001${prefix}000000200000003000400050000
989
990 $controller usbCmdReadHex $command 8 1 [myvar cntr_val]
991 set cntr_new $cntr_val
992
993 if {$cntr_new < $cntr_old} {
994 set rate_val(inst) [expr {($yvec_new - $yvec_old)*20000000/($cntr_old - $cntr_new)}]
995 set rate_val(mean) [expr {($yvec_new - $yvec_bak)*20000000/($cntr_bak - $cntr_new)}]
996 ${config}.chan_frame.entr_value configure -text $yvec_new
997 my stat_update
998
999 set yvec_old $yvec_new
1000 set cntr_old $cntr_new
1001 }
1002 }
1003
1004# -------------------------------------------------------------------------
1005
1006 HstDisplay instproc save_data {data} {
1007 my instvar number
1008
1009 set types {
1010 {{Data Files} {.dat} }
1011 {{All Files} * }
1012 }
1013
1014 set stamp [clock format [clock seconds] -format %Y%m%d_%H%M%S]
1015 set fname spectrum_[expr {$number + 1}]_${stamp}.dat
1016
1017 set fname [tk_getSaveFile -filetypes $types -initialfile $fname]
1018 if {[string equal $fname {}]} {
1019 return
1020 }
1021
1022 set x [catch {
1023 set fid [open $fname w+]
1024 puts $fid $data
1025 close $fid
1026 }]
1027
1028 if { $x || ![file exists $fname] || ![file isfile $fname] || ![file readable $fname] } {
1029 tk_messageBox -icon error \
1030 -message "An error occurred while writing to \"$fname\""
1031 } else {
1032 tk_messageBox -icon info \
1033 -message "File \"$fname\" written successfully"
1034 }
1035 }
1036
1037# -------------------------------------------------------------------------
1038
1039 HstDisplay instproc open_data {} {
1040 set types {
1041 {{Data Files} {.dat} }
1042 {{All Files} * }
1043 }
1044
1045 set fname [tk_getOpenFile -filetypes $types]
1046 if {[string equal $fname {}]} {
1047 return
1048 }
1049
1050 set x [catch {
1051 set fid [open $fname r+]
1052 fconfigure $fid -translation binary -encoding binary
1053 [myvar yvec] set [split [read $fid] \n]
1054 close $fid
1055 }]
1056
1057 if { $x || ![file exists $fname] || ![file isfile $fname] || ![file readable $fname] } {
1058 tk_messageBox -icon error \
1059 -message "An error occurred while reading \"$fname\""
1060 } else {
1061 tk_messageBox -icon info \
1062 -message "File \"$fname\" read successfully"
1063 }
1064 }
1065
1066# -------------------------------------------------------------------------
1067
1068 HstDisplay instproc register {} {
1069 my save_data [join [[myvar yvec] range 0 4095] \n]
1070 }
1071
1072# -------------------------------------------------------------------------
1073
1074 HstDisplay instproc recover {} {
1075 my instvar config
1076 my open_data
1077 ${config}.chan_frame.entr_value configure -text [usb::integrateBlt [myvar yvec] 0 4095 0]
1078 my stat_update
1079 }
1080
1081# -------------------------------------------------------------------------
1082
1083 Class CntDisplay -parameter {
1084 {master}
1085 {controller}
1086 }
1087
1088# -------------------------------------------------------------------------
1089
1090 CntDisplay instproc init {} {
1091
1092 my set data {}
1093 my set cntr 0
1094 my set recs 0
1095
1096 vector create [myvar xvec](10000)
1097 vector create [myvar yvec](10000)
1098
1099 # fill one vector for the x axis with 10000 points
1100 [myvar xvec] seq -0.5 9999.5
1101
1102 my setup
1103
1104 next
1105 }
1106
1107# -------------------------------------------------------------------------
1108
1109 CntDisplay instproc destroy {} {
1110 next
1111 }
1112
1113# -------------------------------------------------------------------------
1114
1115 CntDisplay instproc start {} {
1116 my instvar config
1117
1118 trace add variable [myvar data] write [myproc data_update]
1119
1120 trace add variable [myvar thrs] write [myproc thrs_update]
1121 trace add variable [myvar thrs_val] write [myproc thrs_update]
1122
1123 trace add variable [myvar cntr] write [myproc cntr_update]
1124 trace add variable [myvar recs] write [myproc recs_update]
1125
1126 trace add variable [myvar axis] write [myproc axis_update]
1127
1128 ${config}.axis_check select
1129
1130 ${config}.thrs_check select
1131 ${config}.thrs_field set 25
1132
1133 my set cntr_val 100
1134 my set cntr_bak 100
1135 my set recs_val 100
1136 my set recs_bak 100
1137
1138 ${config}.chan_frame.mean_value configure -text [format {%.2e} 0.0]
1139 ${config}.chan_frame.entr_value configure -text 0.0
1140
1141 ${config}.chan_frame.axisy_value configure -text 0.0
1142 ${config}.chan_frame.axisx_value configure -text 0.0
1143
1144# my cntr_reset
1145 }
1146
1147# -------------------------------------------------------------------------
1148
1149 CntDisplay instproc setup {} {
1150 my instvar master
1151 my instvar xvec yvec graph
1152 my instvar config
1153 my instvar cntr_ms
1154
1155 # create a graph widget and show a grid
1156 set graph [graph ${master}.graph -height 250 -leftmargin 80]
1157 $graph crosshairs configure -hide no -linewidth 1 -color darkblue -dashes {2 2}
1158 $graph grid configure -hide no
1159 $graph legend configure -hide yes
1160
1161 set config [frame ${master}.config -width 170]
1162
1163 checkbutton ${config}.axis_check -text {log scale} -variable [myvar axis]
1164
1165 frame ${config}.spc1 -width 170 -height 30
1166
1167 frame ${config}.chan_frame -borderwidth 0 -width 170
1168 legendLabel ${config}.chan_frame 0 mean {Mean value}
1169 legendLabel ${config}.chan_frame 1 entr {Total entries}
1170 legendLabel ${config}.chan_frame 2 empty {}
1171 legendLabel ${config}.chan_frame 3 axisy {Bin entries}
1172 legendLabel ${config}.chan_frame 4 axisx {Bin number}
1173
1174 frame ${config}.spc3 -width 170 -height 30
1175
1176 checkbutton ${config}.thrs_check -text {amplitude threshold} -variable [myvar thrs]
1177 spinbox ${config}.thrs_field -from 1 -to 4095 \
1178 -increment 5 -width 10 -textvariable [myvar thrs_val] \
1179 -validate all -vcmd {::mca::validate 4095 4 %P}
1180
1181 frame ${config}.spc4 -width 170 -height 30
1182
1183 label ${config}.cntr -text {time of exposure (ms)}
1184 spinbox ${config}.cntr_field -from 0 -to 9999 \
1185 -increment 10 -width 10 -textvariable [myvar cntr_val] \
1186 -validate all -vcmd {::mca::validate 9999 4 %P}
1187
1188 frame ${config}.spc5 -width 170 -height 10
1189
1190 label ${config}.recs -text {number of exposures}
1191 spinbox ${config}.recs_field -from 0 -to 99999 \
1192 -increment 10 -width 10 -textvariable [myvar recs_val] \
1193 -validate all -vcmd {::mca::validate 99999 5 %P}
1194
1195 frame ${config}.spc6 -width 170 -height 10
1196
1197 button ${config}.start -text {Start} \
1198 -bg yellow -activebackground yellow -command [myproc recs_start]
1199
1200 button ${config}.reset -text Reset \
1201 -bg red -activebackground red -command [myproc cntr_reset]
1202
1203 frame ${config}.spc7 -width 170 -height 30
1204
1205 button ${config}.register -text Register \
1206 -bg lightblue -activebackground lightblue -command [myproc register]
1207
1208 frame ${config}.spc8 -width 170 -height 30
1209
1210 button ${config}.recover -text {Read file} \
1211 -bg lightblue -activebackground lightblue -command [myproc recover]
1212
1213 grid ${config}.axis_check -sticky w
1214 grid ${config}.spc1
1215 grid ${config}.chan_frame -sticky ew -padx 5
1216 grid ${config}.spc3
1217 grid ${config}.thrs_check -sticky w
1218 grid ${config}.thrs_field -sticky ew -pady 1 -padx 5
1219 grid ${config}.spc4
1220 grid ${config}.cntr -sticky w -pady 1 -padx 3
1221 grid ${config}.cntr_field -sticky ew -pady 1 -padx 5
1222 grid ${config}.spc5
1223 grid ${config}.recs -sticky w -pady 1 -padx 3
1224 grid ${config}.recs_field -sticky ew -pady 1 -padx 5
1225 grid ${config}.spc6
1226 grid ${config}.start -sticky ew -pady 3 -padx 5
1227 grid ${config}.reset -sticky ew -pady 3 -padx 5
1228 grid ${config}.spc7
1229 grid ${config}.register -sticky ew -pady 3 -padx 5
1230 grid ${config}.spc8
1231 grid ${config}.recover -sticky ew -pady 3 -padx 5
1232
1233 grid ${graph} -row 0 -column 0 -sticky news
1234 grid ${config} -row 0 -column 1
1235
1236 grid rowconfigure ${master} 0 -weight 1
1237 grid columnconfigure ${master} 0 -weight 1
1238 grid columnconfigure ${master} 1 -weight 0 -minsize 80
1239
1240 grid columnconfigure ${config}.chan_frame 1 -weight 1
1241
1242 my crosshairs $graph
1243
1244 #bind .graph <Motion> {%W crosshairs configure -position @%x,%y}
1245
1246 # create one element with data for the x and y axis, no dots
1247 $graph element create Spectrum1 -color blue -linewidth 2 -symbol none -smooth step -xdata [myvar xvec] -ydata [myvar yvec]
1248 }
1249
1250# -------------------------------------------------------------------------
1251
1252 CntDisplay instproc coor_update {W x y} {
1253 my instvar config graph
1254
1255 $W crosshairs configure -position @${x},${y}
1256
1257 set index [$W axis invtransform x $x]
1258 set index [::tcl::mathfunc::round $index]
1259 catch {
1260 ${config}.chan_frame.axisy_value configure -text [[myvar yvec] index $index]
1261 ${config}.chan_frame.axisx_value configure -text ${index}.0
1262 }
1263 }
1264# -------------------------------------------------------------------------
1265
1266 CntDisplay instproc crosshairs {graph} {
1267 set method [myproc coor_update]
1268 bind $graph <Motion> [list [self] coor_update %W %x %y]
1269 bind $graph <Leave> {
1270 %W crosshairs off
1271 }
1272 bind $graph <Enter> {
1273 %W crosshairs on
1274 }
1275 }
1276
1277# -------------------------------------------------------------------------
1278
1279 CntDisplay instproc thrs_update args {
1280 my instvar controller config thrs thrs_val
1281
1282 if {[string equal $thrs_val {}]} {
1283 set thrs_val 0
1284 }
1285
1286 set number 0
1287 set val_addr [format %02x [expr {9 + ${number}}]]
1288
1289 if {$thrs} {
1290 ${config}.thrs_field configure -state normal
1291 set value [format %03x $thrs_val]
1292 } else {
1293 ${config}.thrs_field configure -state disabled
1294 set value 000
1295 }
1296
1297 $controller usbCmd 000200${val_addr}00040${value}
1298 }
1299
1300# -------------------------------------------------------------------------
1301
1302 CntDisplay instproc cntr_update args {
1303 my instvar cntr cntr_val
1304 set cntr_val [expr {${cntr}/20000}]
1305
1306 }
1307
1308# -------------------------------------------------------------------------
1309
1310 CntDisplay instproc recs_update args {
1311 my instvar recs recs_val
1312 set recs_val [expr {${recs}*1}]
1313 }
1314
1315# -------------------------------------------------------------------------
1316
1317 CntDisplay instproc cntr_setup {} {
1318 my instvar controller cntr_val
1319
1320 set cntr_tmp [expr {${cntr_val} * 20000}]
1321 set word0 [format {%08x} [expr {${cntr_tmp} & 0xFFFFFFFF}]]
1322 set word1 [format {%08x} [expr {${cntr_tmp} >> 32}]]
1323
1324 set prefix [format {%x} 9]
1325
1326 set command {}
1327 append command 0001${prefix}000000200000004[string range $word0 4 7]
1328 append command 0001${prefix}000000200010004[string range $word0 0 3]
1329 append command 0001${prefix}000000200020004[string range $word1 4 7]
1330 append command 0001${prefix}000000200030004[string range $word1 0 3]
1331
1332 # send counter value
1333 $controller usbCmd $command
1334 }
1335
1336# -------------------------------------------------------------------------
1337
1338 CntDisplay instproc recs_setup {} {
1339 my instvar controller recs_val
1340
1341 set word0 [format {%08x} [expr {${recs_val} & 0xFFFFFFFF}]]
1342 set word1 [format {%08x} [expr {${recs_val} >> 32}]]
1343
1344 set prefix [format {%x} 10]
1345
1346 set command {}
1347 append command 0001${prefix}000000200000004[string range $word0 4 7]
1348 append command 0001${prefix}000000200010004[string range $word0 0 3]
1349 append command 0001${prefix}000000200020004[string range $word1 4 7]
1350 append command 0001${prefix}000000200030004[string range $word1 0 3]
1351
1352 # send counter value
1353 $controller usbCmd $command
1354 }
1355
1356# -------------------------------------------------------------------------
1357
1358 CntDisplay instproc cntr_reset {} {
1359 my instvar controller after_handle
1360 my instvar cntr_val cntr_bak recs_val recs_bak
1361
1362 my cntr_stop
1363
1364 set value [format {%04x} [expr {1 << 11}]]
1365 $controller usbCmd 000200000004${value}0002000000040000
1366
1367 my recs_stop
1368 }
1369
1370# -------------------------------------------------------------------------
1371
1372 CntDisplay instproc cntr_ready {} {
1373 my instvar config cntr_val cntr_bak recs_val recs_bak
1374
1375 set cntr_val $cntr_bak
1376 set recs_val $recs_bak
1377
1378 ${config}.start configure -text Start -command [myproc recs_start]
1379 ${config}.reset configure -state active
1380
1381 ${config}.cntr_field configure -state normal
1382 ${config}.recs_field configure -state normal
1383 }
1384
1385# -------------------------------------------------------------------------
1386
1387 CntDisplay instproc recs_start {} {
1388 my instvar controller config auto
1389 my instvar cntr_val cntr_bak recs_val recs_bak
1390
1391 if {$cntr_val > 0 && $recs_val > 0} {
1392 ${config}.start configure -text {Stop} -command [myproc recs_stop]
1393 ${config}.cntr_field configure -state disabled
1394 ${config}.recs_field configure -state disabled
1395
1396 set cntr_bak $cntr_val
1397 set recs_bak $recs_val
1398
1399 my cntr_setup
1400 my recs_setup
1401
1402 set val_addr [format {%02x} 16]
1403
1404 $controller usbCmd 000200${val_addr}00040002
1405
1406 set auto 1
1407
1408 after 100 [myproc acquire_loop]
1409 }
1410 }
1411
1412# -------------------------------------------------------------------------
1413
1414 CntDisplay instproc recs_stop {} {
1415 my instvar cntr_val cntr_bak recs_val recs_bak
1416
1417 my cntr_stop
1418
1419 set cntr_val $cntr_bak
1420 my cntr_setup
1421
1422 set recs_val $recs_bak
1423 my recs_setup
1424
1425 my acquire
1426
1427 my cntr_ready
1428 }
1429
1430# -------------------------------------------------------------------------
1431
1432 CntDisplay instproc cntr_stop {} {
1433 my instvar controller config auto
1434
1435 set val_addr [format {%02x} 16]
1436
1437 $controller usbCmd 000200${val_addr}00040000
1438
1439 set auto 0
1440 }
1441
1442# -------------------------------------------------------------------------
1443
1444 CntDisplay instproc acquire_loop {} {
1445 my instvar recs_val auto
1446
1447 my acquire
1448
1449 if {$recs_val == 0} {
1450 my cntr_stop
1451 my cntr_ready
1452 } elseif {$auto} {
1453 after 1000 [myproc acquire_loop]
1454 }
1455 }
1456
1457# -------------------------------------------------------------------------
1458
1459 CntDisplay instproc data_update args {
1460 my instvar config data
1461 usb::convertBlt $data 2 [myvar yvec]
1462
1463 ${config}.chan_frame.mean_value configure \
1464 -text [format {%.2e} [usb::integrateBlt [myvar yvec] 0 9999 1]]
1465 ${config}.chan_frame.entr_value configure \
1466 -text [usb::integrateBlt [myvar yvec] 0 9999 0]
1467
1468 }
1469
1470# -------------------------------------------------------------------------
1471
1472 CntDisplay instproc axis_update args {
1473 my instvar axis graph
1474 $graph axis configure x -min 0 -max 10000
1475 Blt_ZoomStack $graph
1476 if {$axis} {
1477 $graph axis configure y -min 1 -max 1E5 -logscale yes
1478 } else {
1479 $graph axis configure y -min {} -max {} -logscale no
1480 }
1481 }
1482
1483# -------------------------------------------------------------------------
1484
1485 CntDisplay instproc acquire {} {
1486 my instvar controller config
1487 my instvar cntr cntr_val recs recs_val
1488
1489 set size 10000
1490
1491 set prefix [format {%x} 8]
1492
1493 set value [format {%08x} $size]
1494
1495 set command 0001${prefix}000000200000001[string range $value 0 3]0003[string range $value 4 7]00050000
1496
1497 $controller usbCmdReadRaw $command [expr {$size * 2}] [myvar data]
1498
1499 set prefix [format {%x} 9]
1500 set command 0001${prefix}000000200000003000400050000
1501
1502 $controller usbCmdReadHex $command 8 1 [myvar cntr]
1503
1504 set prefix [format {%x} 10]
1505 set command 0001${prefix}000000200000003000400050000
1506
1507 $controller usbCmdReadHex $command 8 1 [myvar recs]
1508 }
1509
1510# -------------------------------------------------------------------------
1511
1512 CntDisplay instproc save_data {data} {
1513
1514 set types {
1515 {{Data Files} {.dat} }
1516 {{All Files} * }
1517 }
1518
1519 set stamp [clock format [clock seconds] -format %Y%m%d_%H%M%S]
1520 set fname counts_${stamp}.dat
1521
1522 set fname [tk_getSaveFile -filetypes $types -initialfile $fname]
1523 if {[string equal $fname {}]} {
1524 return
1525 }
1526
1527 set x [catch {
1528 set fid [open $fname w+]
1529 puts $fid $data
1530 close $fid
1531 }]
1532
1533 if { $x || ![file exists $fname] || ![file isfile $fname] || ![file readable $fname] } {
1534 tk_messageBox -icon error \
1535 -message "An error occurred while writing to \"$fname\""
1536 } else {
1537 tk_messageBox -icon info \
1538 -message "File \"$fname\" written successfully"
1539 }
1540 }
1541
1542# -------------------------------------------------------------------------
1543
1544 CntDisplay instproc open_data {} {
1545 set types {
1546 {{Data Files} {.dat} }
1547 {{All Files} * }
1548 }
1549
1550 set fname [tk_getOpenFile -filetypes $types]
1551 if {[string equal $fname {}]} {
1552 return
1553 }
1554
1555 set x [catch {
1556 set fid [open $fname r+]
1557 fconfigure $fid -translation binary -encoding binary
1558 [myvar yvec] set [split [read $fid] \n]
1559 close $fid
1560 }]
1561
1562 if { $x || ![file exists $fname] || ![file isfile $fname] || ![file readable $fname] } {
1563 tk_messageBox -icon error \
1564 -message "An error occurred while reading \"$fname\""
1565 } else {
1566 tk_messageBox -icon info \
1567 -message "File \"$fname\" read successfully"
1568 }
1569 }
1570
1571# -------------------------------------------------------------------------
1572
1573 CntDisplay instproc register {} {
1574 my save_data [join [[myvar yvec] range 0 9999] \n]
1575 }
1576
1577# -------------------------------------------------------------------------
1578
1579 CntDisplay instproc recover {} {
1580 my open_data
1581 }
1582
1583# -------------------------------------------------------------------------
1584
1585 Class OscDisplay -parameter {
1586 {master}
1587 {controller}
1588 }
1589
1590# -------------------------------------------------------------------------
1591
1592 OscDisplay instproc init {} {
1593 my instvar sequence data xvec yvec
1594
1595 set data {}
1596
1597 set sequence 0
1598
1599# set xvec [vector create #auto(262144)]
1600 set xvec [vector create #auto(10000)]
1601
1602 for {set i 1} {$i <= 9} {incr i} {
1603# dict set yvec $i [vector create #auto(262144)]
1604 dict set yvec $i [vector create #auto(10000)]
1605 }
1606
1607 # fill one vector for the x axis
1608# $xvec seq 0 262143
1609 $xvec seq 0 10000
1610
1611 my setup
1612
1613 next
1614 }
1615
1616# -------------------------------------------------------------------------
1617
1618 OscDisplay instproc destroy {} {
1619 next
1620 }
1621
1622# -------------------------------------------------------------------------
1623
1624 OscDisplay instproc start {} {
1625 my instvar config
1626 my instvar recs_val directory
1627
1628 set directory $::env(HOMEPATH)
1629 set recs_val 100
1630
1631 trace add variable [myvar chan] write [myproc chan_update]
1632
1633 trace add variable [myvar data] write [myproc data_update]
1634
1635 trace add variable [myvar auto] write [myproc auto_update]
1636
1637 trace add variable [myvar thrs] write [myproc thrs_update 0]
1638 trace add variable [myvar thrs_val] write [myproc thrs_update 0]
1639
1640 trace add variable [myvar recs_val] write [myproc recs_val_update]
1641
1642 trace add variable [myvar last] write [myproc last_update]
1643
1644 for {set i 1} {$i <= 6} {incr i} {
1645 ${config}.chan_frame.chan${i}_check select
1646 ${config}.chan_frame.chan${i}_value configure -text 0.0
1647 }
1648 ${config}.chan_frame.axisx_value configure -text 0.0
1649
1650 ${config}.thrs_check select
1651 ${config}.thrs_field set 100
1652 }
1653
1654# -------------------------------------------------------------------------
1655
1656 OscDisplay instproc setup {} {
1657 my instvar master
1658 my instvar xvec yvec graph
1659 my instvar config
1660
1661 # create a graph widget and show a grid
1662 set graph [graph ${master}.graph -height 250 -leftmargin 80]
1663 $graph crosshairs configure -hide no -linewidth 1 -color darkblue -dashes {2 2}
1664 $graph grid configure -hide no
1665 $graph legend configure -hide yes
1666 $graph axis configure x -min 0 -max 10000
1667 $graph axis configure y -min 0 -max 4100
1668
1669# scale ${master}.last -orient horizontal -from 1 -to 27 -tickinterval 0 -showvalue no -variable [myvar last]
1670
1671 set config [frame ${master}.config -width 170]
1672
1673 frame ${config}.chan_frame -width 170
1674 legendButton ${config}.chan_frame 0 chan1 {Channel 1} [myvar chan(1)] turquoise2
1675 legendButton ${config}.chan_frame 1 chan2 {Channel 2} [myvar chan(2)] SpringGreen2
1676 legendButton ${config}.chan_frame 2 chan3 {Channel 3} [myvar chan(3)] orchid2
1677 legendButton ${config}.chan_frame 3 chan4 {Channel 4} [myvar chan(4)] orange2
1678 legendButton ${config}.chan_frame 4 chan5 {Channel 5} [myvar chan(5)] blue1 white
1679 legendButton ${config}.chan_frame 5 chan6 {Channel 6} [myvar chan(6)] gray65 white
1680 legendLabel ${config}.chan_frame 6 axisx {Time axis}
1681
1682 frame ${config}.spc1 -width 170 -height 30
1683
1684 checkbutton ${config}.auto_check -text {auto update} -variable [myvar auto]
1685
1686 frame ${config}.spc2 -width 170 -height 30
1687
1688 checkbutton ${config}.thrs_check -text threshold -variable [myvar thrs]
1689 spinbox ${config}.thrs_field -from 1 -to 4095 \
1690 -increment 5 -width 10 -textvariable [myvar thrs_val] \
1691 -validate all -vcmd {::mca::validate 4095 4 %P}
1692
1693 frame ${config}.spc3 -width 170 -height 30
1694
1695 button ${config}.acquire -text Acquire \
1696 -bg green -activebackground green -command [myproc acquire_start]
1697 button ${config}.register -text Register \
1698 -bg lightblue -activebackground lightblue -command [myproc register]
1699
1700 frame ${config}.spc4 -width 170 -height 30
1701
1702 label ${config}.recs -text {number of records}
1703 spinbox ${config}.recs_field -from 0 -to 10000 \
1704 -increment 10 -width 10 -textvariable [myvar recs_val] \
1705 -validate all -vcmd {::mca::validate 10000 5 %P}
1706
1707 frame ${config}.spc5 -width 170 -height 10
1708
1709 button ${config}.sequence -text {Start Recording} -command [myproc sequence_start] \
1710 -bg yellow -activebackground yellow
1711
1712 frame ${config}.spc6 -width 170 -height 30
1713
1714 button ${config}.recover -text {Read file} \
1715 -bg lightblue -activebackground lightblue -command [myproc recover]
1716
1717 grid ${config}.chan_frame -sticky ew
1718 grid ${config}.spc1
1719 grid ${config}.auto_check -sticky w
1720 grid ${config}.spc2
1721 grid ${config}.thrs_check -sticky w
1722 grid ${config}.thrs_field -sticky ew -pady 1 -padx 5
1723 grid ${config}.spc3
1724 grid ${config}.acquire -sticky ew -pady 3 -padx 5
1725 grid ${config}.register -sticky ew -pady 3 -padx 5
1726 grid ${config}.spc4
1727 grid ${config}.recs -sticky w -pady 1 -padx 3
1728 grid ${config}.recs_field -sticky ew -pady 1 -padx 5
1729 grid ${config}.spc5
1730 grid ${config}.sequence -sticky ew -pady 3 -padx 5
1731 grid ${config}.spc6
1732 grid ${config}.recover -sticky ew -pady 3 -padx 5
1733
1734 grid ${graph} -row 0 -column 0 -sticky news
1735 grid ${config} -row 0 -column 1
1736
1737# grid ${master}.last -row 1 -column 0 -columnspan 2 -sticky ew
1738
1739 grid rowconfigure ${master} 0 -weight 1
1740 grid columnconfigure ${master} 0 -weight 1
1741 grid columnconfigure ${master} 1 -weight 0 -minsize 120
1742
1743 grid columnconfigure ${config}.chan_frame 2 -weight 1
1744
1745 # enable zooming
1746 Blt_ZoomStack $graph
1747
1748 my crosshairs $graph
1749
1750 # create one element with data for the x and y axis, no dots
1751 $graph pen create pen1 -color turquoise3 -linewidth 2 -symbol none
1752 $graph pen create pen2 -color SpringGreen3 -linewidth 2 -symbol none
1753 $graph pen create pen3 -color orchid3 -linewidth 2 -symbol none
1754 $graph pen create pen4 -color orange3 -linewidth 2 -symbol none
1755 $graph pen create pen5 -color blue2 -linewidth 2 -symbol none
1756 $graph pen create pen6 -color gray55 -linewidth 2 -symbol none
1757
1758 $graph element create Spectrum1 -pen pen1 -xdata $xvec -ydata [dict get $yvec 1]
1759 $graph element create Spectrum2 -pen pen2 -xdata $xvec -ydata [dict get $yvec 2]
1760 $graph element create Spectrum3 -pen pen3 -xdata $xvec -ydata [dict get $yvec 3]
1761 $graph element create Spectrum4 -pen pen4 -xdata $xvec -ydata [dict get $yvec 4]
1762 $graph element create Spectrum5 -pen pen5 -xdata $xvec -ydata [dict get $yvec 5]
1763 $graph element create Spectrum6 -pen pen6 -xdata $xvec -ydata [dict get $yvec 6]
1764 }
1765
1766# -------------------------------------------------------------------------
1767
1768 OscDisplay instproc coor_update {W x y} {
1769 my instvar xvec yvec graph
1770 my instvar config
1771
1772 $W crosshairs configure -position @${x},${y}
1773
1774 set index [$W axis invtransform x $x]
1775 set index [::tcl::mathfunc::round $index]
1776 catch {
1777 ${config}.chan_frame.chan1_value configure -text [[dict get $yvec 1] index $index]
1778 ${config}.chan_frame.chan2_value configure -text [[dict get $yvec 2] index $index]
1779 ${config}.chan_frame.chan3_value configure -text [[dict get $yvec 3] index $index]
1780 ${config}.chan_frame.chan4_value configure -text [[dict get $yvec 4] index $index]
1781 ${config}.chan_frame.chan5_value configure -text [[dict get $yvec 5] index $index]
1782 ${config}.chan_frame.chan6_value configure -text [[dict get $yvec 6] index $index]
1783 ${config}.chan_frame.axisx_value configure -text ${index}.0
1784 }
1785 }
1786# -------------------------------------------------------------------------
1787
1788 OscDisplay instproc crosshairs {graph} {
1789 set method [myproc coor_update]
1790 bind $graph <Motion> [list [self] coor_update %W %x %y]
1791 bind $graph <Leave> {
1792 %W crosshairs off
1793 }
1794 bind $graph <Enter> {
1795 %W crosshairs on
1796 }
1797 }
1798
1799# -------------------------------------------------------------------------
1800
1801 OscDisplay instproc chan_update {name key op} {
1802 my instvar config graph chan
1803
1804 if {$chan(${key})} {
1805 $graph pen configure pen${key} -linewidth 2
1806 } else {
1807 $graph pen configure pen${key} -linewidth 0
1808 }
1809 }
1810
1811# -------------------------------------------------------------------------
1812
1813 OscDisplay instproc recs_val_update args {
1814 my instvar recs_val
1815 if {[string equal $recs_val {}]} {
1816 set recs_val 0
1817 }
1818 }
1819
1820# -------------------------------------------------------------------------
1821
1822 OscDisplay instproc last_update args {
1823 my instvar graph last
1824
1825 set first [expr {$last - 1}]
1826
1827 $graph axis configure x -min ${first}0000 -max ${last}0000
1828 }
1829
1830# -------------------------------------------------------------------------
1831
1832 OscDisplay instproc thrs_update {reset args} {
1833 my instvar controller config thrs thrs_val
1834
1835 if {[string equal $thrs_val {}]} {
1836 set thrs_val 0
1837 }
1838
1839 if {$thrs} {
1840 ${config}.thrs_field configure -state normal
1841 set value [format %03x $thrs_val]
1842 } else {
1843 ${config}.thrs_field configure -state disabled
1844 set value 000
1845 }
1846
1847 set command {}
1848 if {$reset} {
1849 append command 0002000500041${value}
1850 }
1851 append command 0002000500040${value}
1852
1853 $controller usbCmd $command
1854 }
1855
1856# -------------------------------------------------------------------------
1857
1858 OscDisplay instproc data_update args {
1859 my instvar data yvec
1860 my instvar graph chan waiting sequence auto
1861
1862 usb::convertOsc $data $yvec
1863
1864 foreach {key value} [array get chan] {
1865 $graph pen configure pen${key} -dashes 0
1866 }
1867
1868 set waiting 0
1869
1870 if {$sequence} {
1871 my sequence_register
1872 } elseif {$auto} {
1873 after 1000 [myproc acquire_start]
1874 }
1875 }
1876
1877# -------------------------------------------------------------------------
1878
1879 OscDisplay instproc acquire_start {} {
1880 my instvar graph chan controller waiting
1881
1882 foreach {key value} [array get chan] {
1883 $graph pen configure pen${key} -dashes dot
1884 }
1885
1886 # restart
1887 my thrs_update 1
1888
1889 set waiting 1
1890
1891 after 200 [myproc acquire_loop]
1892 }
1893
1894# -------------------------------------------------------------------------
1895
1896 OscDisplay instproc acquire_loop {} {
1897 my instvar controller waiting
1898
1899# set size 262144
1900 set size 10000
1901
1902 set value [format {%08x} [expr {$size * 4}]]
1903
1904 set command 00011000000200000001[string range $value 0 3]0003[string range $value 4 7]00050000
1905
1906 $controller usbCmdReadRaw $command [expr {$size * 8}] [myvar data]
1907
1908 if {$waiting} {
1909 after 200 [myproc acquire_loop]
1910 }
1911 }
1912
1913# -------------------------------------------------------------------------
1914
1915 OscDisplay instproc auto_update args {
1916 my instvar config auto
1917
1918 if {$auto} {
1919 ${config}.recs_field configure -state disabled
1920 ${config}.sequence configure -state disabled
1921 ${config}.acquire configure -state disabled
1922 ${config}.register configure -state disabled
1923 ${config}.recover configure -state disabled
1924
1925 my acquire_start
1926 } else {
1927 ${config}.recs_field configure -state normal
1928 ${config}.sequence configure -state active
1929 ${config}.acquire configure -state active
1930 ${config}.register configure -state active
1931 ${config}.recover configure -state active
1932 }
1933 }
1934
1935# -------------------------------------------------------------------------
1936
1937 OscDisplay instproc save_data {fname} {
1938 my instvar data
1939
1940 set fid [open $fname w+]
1941 fconfigure $fid -translation binary -encoding binary
1942
1943# puts -nonewline $fid [binary format "H*iH*" "1f8b0800" [clock seconds] "0003"]
1944# puts -nonewline $fid [zlib deflate $data]
1945 puts -nonewline $fid $data
1946# puts -nonewline $fid [binary format i [zlib crc32 $data]]
1947# puts -nonewline $fid [binary format i [string length $data]]
1948
1949 close $fid
1950 }
1951
1952# -------------------------------------------------------------------------
1953
1954 OscDisplay instproc open_data {} {
1955 set types {
1956 {{Data Files} {.dat} }
1957 {{All Files} * }
1958 }
1959
1960 set fname [tk_getOpenFile -filetypes $types]
1961 if {[string equal $fname {}]} {
1962 return
1963 }
1964
1965 set x [catch {
1966 set fid [open $fname r+]
1967 fconfigure $fid -translation binary -encoding binary
1968# set size [file size $fname]
1969# seek $fid 10
1970# my set data [zlib inflate [read $fid [expr {$size - 18}]]]
1971 my set data [read $fid]
1972 close $fid
1973 }]
1974
1975 if { $x || ![file exists $fname] || ![file isfile $fname] || ![file readable $fname] } {
1976 tk_messageBox -icon error \
1977 -message "An error occurred while reading \"$fname\""
1978 } else {
1979 tk_messageBox -icon info \
1980 -message "File \"$fname\" read successfully"
1981 }
1982 }
1983
1984# -------------------------------------------------------------------------
1985
1986 OscDisplay instproc register {} {
1987 set types {
1988 {{Data Files} {.dat} }
1989 {{All Files} * }
1990 }
1991
1992 set stamp [clock format [clock seconds] -format %Y%m%d_%H%M%S]
1993 set fname oscillogram_${stamp}.dat
1994
1995 set fname [tk_getSaveFile -filetypes $types -initialfile $fname]
1996 if {[string equal $fname {}]} {
1997 return
1998 }
1999
2000 if {[catch {my save_data $fname} result]} {
2001 tk_messageBox -icon error \
2002 -message "An error occurred while writing to \"$fname\""
2003 } else {
2004 tk_messageBox -icon info \
2005 -message "File \"$fname\" written successfully"
2006 }
2007 }
2008
2009# -------------------------------------------------------------------------
2010
2011 OscDisplay instproc recover {} {
2012 my open_data
2013 }
2014
2015# -------------------------------------------------------------------------
2016
2017 OscDisplay instproc sequence_start {} {
2018 my instvar config recs_val recs_bak directory counter sequence
2019
2020 set counter 1
2021 if {$counter > $recs_val} {
2022 return
2023 }
2024
2025 set directory [tk_chooseDirectory -initialdir $directory -title {Choose a directory}]
2026
2027 if {[string equal $directory {}]} {
2028 return
2029 }
2030
2031 ${config}.recs_field configure -state disabled
2032 ${config}.sequence configure -text {Stop Recording} -command [myproc sequence_stop]
2033 ${config}.acquire configure -state disabled
2034 ${config}.register configure -state disabled
2035 ${config}.recover configure -state disabled
2036
2037 set recs_bak $recs_val
2038
2039 set sequence 1
2040
2041 my acquire_start
2042 }
2043
2044# -------------------------------------------------------------------------
2045
2046 OscDisplay instproc sequence_register {} {
2047 my instvar config recs_val recs_bak directory counter
2048
2049 set fname [file join $directory oscillogram_$counter.dat]
2050
2051 my incr counter
2052
2053 if {[catch {my save_data $fname} result]} {
2054 tk_messageBox -icon error \
2055 -message "An error occurred while writing to \"$fname\""
2056 } elseif {$counter <= $recs_bak} {
2057 set recs_val [expr {$recs_bak - $counter}]
2058 my acquire_start
2059 return
2060 }
2061
2062 my sequence_stop
2063 }
2064
2065# -------------------------------------------------------------------------
2066
2067 OscDisplay instproc sequence_stop {} {
2068 my instvar config recs_val recs_bak sequence
2069
2070 set sequence 0
2071
2072 set recs_val $recs_bak
2073
2074 ${config}.recs_field configure -state normal
2075 ${config}.sequence configure -text {Start Recording} -command [myproc sequence_start]
2076 ${config}.acquire configure -state active
2077 ${config}.register configure -state active
2078 ${config}.recover configure -state active
2079 }
2080
2081# -------------------------------------------------------------------------
2082
2083 namespace export MuxDisplay
2084 namespace export HstDisplay
2085 namespace export CntDisplay
2086 namespace export OscDisplay
2087}
2088
2089set notebook [::blt::tabnotebook .notebook -borderwidth 1 -selectforeground black -side bottom]
2090
2091grid ${notebook} -row 0 -column 0 -sticky news -pady 5
2092
2093grid rowconfigure . 0 -weight 1
2094grid columnconfigure . 0 -weight 1
2095
2096::mca::UsbController usb
2097
2098set window [frame ${notebook}.hst_0]
2099$notebook insert end -text "Spectrum histogram 1" -window $window -fill both
2100::mca::HstDisplay hst_0 -number 0 -master $window -controller usb
2101
2102set window [frame ${notebook}.hst_1]
2103$notebook insert end -text "Spectrum histogram 2" -window $window -fill both
2104::mca::HstDisplay hst_1 -number 1 -master $window -controller usb
2105
2106set window [frame ${notebook}.cnt_0]
2107$notebook insert end -text "Rate histogram" -window $window -fill both
2108::mca::CntDisplay cnt_0 -master $window -controller usb
2109
2110set window [frame ${notebook}.mux]
2111$notebook insert end -text "Interconnect" -window $window -fill both
2112::mca::MuxDisplay mux -master $window -controller usb
2113
2114set window [frame ${notebook}.ept]
2115$notebook insert end -text "Oscilloscope" -window $window -fill both
2116::mca::OscDisplay osc -master $window -controller usb
2117
2118update
2119
2120usb usbCmd 00000000
2121
2122hst_0 start
2123
2124hst_1 start
2125
2126cnt_0 start
2127
2128mux start
2129
2130osc start
Note: See TracBrowser for help on using the repository browser.