source: trunk/MultiChannelUSB/UserInterface.tcl@ 170

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

add information header to histogram file

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