| Bsoft 2.0.5 Bernard's software package

bshow_image.tcl
Go to the documentation of this file.
1 ##
2 # @file bshow_image.tcl
3 #
4 # @brief Procedures for manipulating images in Bshow.
5 #
6 # @author Bernard Heymann
7 # @date Created: 20010516
8 # @date Modified: 20191001
9
10 set show_mont 1
11 set show_mont_labels 1
12 set show_mont_select 1
13 set avg_check 0
14 set kernel 1
15 set lg 0
16 set avgtileps 0
17 set avgframeps 0
18 set tiled 0
19 set tilex 512
20 set tiley 512
21 set tilez 512
22 set defocus 2.0
23
24 ## @brief Menu for manipulating image files
25 #
26
27 proc setupImageMenu {} {
28 .menuBar add cascade -menu .menuBar.image -label "Image" -underline 0
29 menu .menuBar.image -tearoff 0
30 .menuBar.image add command -label "Set scales" -underline 0 \
31 -command { setScaleDialog } -accelerator "Ctrl-z"
32 .menuBar.image add command -label "Switch slices and images" -underline 0 \
33 -command { switchImage }
34 .menuBar.image add command -label "Modify image" -underline 0 \
35 -command { modifyImage }
36
37 menu .menuBar.image.dt -tearoff 0
38 .menuBar.image add cascade -menu .menuBar.image.dt -label "Change data type" -underline 0
39 .menuBar.image.dt add command -label "Unsigned char (byte)" -underline 0 \
40 -command { changeDataType byte } -accelerator "Ctrl-z"
41 .menuBar.image.dt add command -label "Signed char" -underline 0 \
42 -command { changeDataType char } -accelerator "Ctrl-z"
43 .menuBar.image.dt add command -label "Unsigned short" -underline 0 \
44 -command { changeDataType "unsigned short" } -accelerator "Ctrl-z"
45 .menuBar.image.dt add command -label "Signed short" -underline 0 \
46 -command { changeDataType short } -accelerator "Ctrl-z"
47 .menuBar.image.dt add command -label "Unsigned int" -underline 0 \
48 -command { changeDataType "unsigned int" } -accelerator "Ctrl-z"
49 .menuBar.image.dt add command -label "Signed int" -underline 0 \
50 -command { changeDataType int } -accelerator "Ctrl-z"
51 .menuBar.image.dt add command -label "Unsigned long" -underline 0 \
52 -command { changeDataType "unsigned long" } -accelerator "Ctrl-z"
53 .menuBar.image.dt add command -label "Signed long" -underline 0 \
54 -command { changeDataType long } -accelerator "Ctrl-z"
55 .menuBar.image.dt add command -label "Float" -underline 0 \
56 -command { changeDataType float } -accelerator "Ctrl-z"
57 .menuBar.image.dt add command -label "Double" -underline 0 \
58 -command { changeDataType double } -accelerator "Ctrl-z"
59
60 .menuBar.image add command -label "Fix type sign" -underline 0 \
61 -command { fixType }
62 .menuBar.image add command -label "Set origin" -underline 0 \
63 -command { setOrigin }
64 .menuBar.image add command -label "Center origin" -underline 0 \
65 -command { centerOrigin }
66 .menuBar.image add command -label "Shift origin to zero" -underline 0 \
67 -command { zeroOrigin }
68 .menuBar.image add command -label "Crop" -underline 0 \
69 -command { cropImage }
70 .menuBar.image add command -label "Pad" -underline 0 \
71 -command { Pad }
72 .menuBar.image add command -label "Bin" -underline 0 \
73 -command { Bin }
74 .menuBar.image add command -label "Montage" -underline 0 \
75 -command { Montage }
76 .menuBar.image add command -label "Invert" -underline 0 \
77 -command { invertImage }
78 .menuBar.image add command -label "Histogram" -underline 0 \
79 -command { Histogram }
80 .menuBar.image add command -label "Filter" -underline 0 \
81 -command { Filter }
82 .menuBar.image add command -label "Fourier transform" -underline 0 \
83 -command { FourierTransform -1 }
84 .menuBar.image add command -label "Fourier back transform" -underline 0 \
85 -command { FourierTransform 1 }
86 .menuBar.image add command -label "Power spectrum" -underline 0 \
87 -command { PowerSpectrum }
88 .menuBar.image add command -label "Diffraction" -underline 0 \
89 -command { Diffraction }
90
91
92 }
93
94 ## @brief Switches the images and slices.
95 #
96
97 proc switchImage { } {
98 global theimg
99 Bimage switch $theimg
100 reconfigureScales
101 Update 1
102 }
103
104 ## @brief Sets the image type.
105 #
106
107 proc setImageType { } {
108 global imgtype
109 set w .wtyp
110 if ![winfo exists $w] {
111 toplevel $w
112
113 radiobutton $w.notdef -text "Not defined" -variable imgtype -value ""
114 radiobutton $w.mg -text "Micrograph(s)" -variable imgtype -value "mg"
115 radiobutton $w.frame -text "Frame(s)" -variable imgtype -value "frame"
116 radiobutton $w.part -text "Particle(s)" -variable imgtype -value "part"
117 radiobutton $w.fil -text "Filament(s)" -variable imgtype -value "fil"
118 radiobutton $w.ft -text "Fourier transform(s)" -variable imgtype -value "ft"
119 radiobutton $w.ps -text "Power spectrum(s)" -variable imgtype -value "ps"
120 radiobutton $w.rec -text "Reconstruction(s)" -variable imgtype -value "rec"
121
122 frame $w.buttons
123 button $w.buttons.ok -text OK -command "destroy $w"
124
125 pack $w.notdef $w.mg $w.frame $w.part $w.fil $w.ft \
126 $w.ps $w.rec $w.buttons -side top -fill x -pady 5
127 pack $w.buttons.ok -side left -expand 1
128
129 bind $w <Return> "destroy $w"
130 } else {
131 wm deiconify $w
132 raise $w
133 }
134 wm title $w "Image type"
135 wm iconname $w "Image type"
136 tkwait window $w
137 }
138
139
140 ## @brief Switchs the sign convention for the data type.
141 #
142
143 proc fixType { } {
144 global theimg
145 Bimage fixtype $theimg
146 reconfigureScales
147 Update 1
148 }
149
150 ## @brief Sets the image origin.
151 #
152
153 proc setOrigin { } {
154 global theimg
155 global helv12
156
157 set ori [Bimage get $theimg origin]
158
159 set w .ori
160 catch {destroy $w}
161 toplevel $w
162 wm title $w "Set origin"
163 wm iconname $w "Origin"
164
165 label $w.msg -font $helv12 -wraplength 4i -justify left \
166 -text {Selecting OK sets the image origin}
167 pack $w.msg -side top -padx 5 -pady 5
168
169 setupSizeEntry $w.coor "Coordinates" double $ori "The image origin coordinates"
170 pack $w.coor -side top -fill x -pady 2m
171
172 frame $w.buttons
173 button $w.buttons.center -text Center -command "setImageOrigin $w 1"
174 button $w.buttons.ok -text OK -command "setImageOrigin $w 0"
175 button $w.buttons.cancel -text Cancel -command "destroy $w"
176
177 pack $w.buttons -side bottom -fill x -pady 2m
178 pack $w.buttons.center $w.buttons.ok $w.buttons.cancel -side left -expand 1
179
180 bind $w <Return> "setImageOrigin $w 0"
181 }
182
183 ## @brief Sets the image origin.
184 #
185 # @param w window.
186 # @param t 0=coordinates, 1=center.
187
188 proc setImageOrigin { w t } {
189 global theimg
190 if { $t } {
191 set ox [expr [Bimage get $theimg width] / 2]
192 set oy [expr [Bimage get $theimg height] / 2]
193 set oz [expr [Bimage get $theimg nslices] / 2]
194 } else {
195 set ox [$w.coor.x get]
196 set oy [$w.coor.y get]
197 set oz [$w.coor.z get]
198 }
199 Bimage set $theimg origin $ox $oy $oz
200 destroy $w
201 reconfigureScales
202 Update 1
203 }
204
205 ## @brief Gets the x origin in canvas coordinates.
206 #
207 # @param c Canvas object.
208
209 proc getOriginX { c } {
210 global theimg
211 set wc [getControlWindow $theimg]
212 set scale [$wc.scale.scale get]
213 set origin [Bimage get $theimg origin]
214 return [expr $scale * [lindex $origin 0]]
215 }
216
217 ## @brief Gets the y origin in canvas coordinates.
218 #
219 # @param c Canvas object.
220
221 proc getOriginY { c } {
222 global theimg
223 set wc [getControlWindow $theimg]
224 set h [lindex [$c cget -scrollregion] 3]
225 set scale [$wc.scale.scale get]
226 set origin [Bimage get $theimg origin]
227 return [expr $h - $scale * ([lindex $origin 1] + 1)]
228 }
229
230 ## @brief Centers the image origin with wrapping.
231 #
232
233 proc centerOrigin { } {
234 global theimg
235 global project_item
236 if ![Bimage exists $theimg] { return}
237 Bimage center $theimg
238 set origin [Bimage get $theimg origin]
239 if [Bmg exists] {
240 Bmg set $project_item origin [lindex $origin 0] [lindex $origin 1] [lindex $origin 2]
241 }
242 Update 1
243 }
244
245 ## @brief Shifts the image origin to zero {0,0,0} with wrapping.
246 #
247
248 proc zeroOrigin { } {
249 global theimg
250 global project_item
251 if ![Bimage exists $theimg] { return}
252 Bimage zero_origin $theimg
253 set origin [Bimage get $theimg origin]
254 if [Bmg exists] {
255 Bmg set $project_item origin [lindex $origin 0] [lindex $origin 1] [lindex $origin 2]
256 }
257 Update 1
258 }
259
260 ## @brief Extracts part of an image.
261 #
262
263 proc extractImage { } {
264 global theimg
265 global filename
266 global imgdir
267 global filetypes
268 global tool
269 global sx1 sx2 sy1 sy2 sz1 sz2
270 if ![Bimage exists $theimg] { return}
271 set wc [getControlWindow $theimg]
272 set x [Bimage get $theimg width]
273 set y [Bimage get $theimg height]
274 set z [$wc.slice.scale get]
275 set vlist "0 0 $z $x $y $z"
276 if { [winfo exists .wsel] && $tool == "select" } {
277 if { $sx1 != $sx2 || $sy1 != $sy2 } {
278 set vlist "$sx1 $sy1 $sz1 $sx2 $sy2 $sz2"
279 }
280 }
281 # puts $vlist
282 set img_num [$wc.image.scale get]
283 set currdir $imgdir
284 if { [string length $currdir] < 2 } { set currdir [pwd]}
285 set extfile [tk_getSaveFile -filetypes $filetypes \
286 -initialfile [file tail $filename] -initialdir $currdir -defaultextension .pif]
287 if { [string length $extfile] < 1 } { return}
288 Bimage extract $theimg $extfile $img_num $vlist
289 }
290
291 ## @brief Crops an image to a smaller size.
292 #
293
294 proc cropImage { } {
295 global theimg
296 global tool
297 global sx1 sx2 sy1 sy2 sz1 sz2
298 if ![Bimage exists $theimg] { return}
299 set wc [getControlWindow $theimg]
300 set img_num [$wc.image.scale get]
301 set x [Bimage get $theimg width]
302 set y [Bimage get $theimg height]
303 set z [$wc.slice.scale get]
304 set vlist "0 0 $z $x $y $z"
305 if { [winfo exists .wsel] && $tool == "select" } {
306 set vlist "$sx1 $sy1 $sz1 $sx2 $sy2 $sz2"
307 set sx1 0
308 set sx2 0
309 set sy1 0
310 set sy2 0
311 set sz1 0
312 set sz2 0
313 }
314 # puts $vlist
315 Bimage crop $theimg $img_num $vlist
316 reconfigureScales
317 Update 1
318 }
319
320 ## @brief Pads an image to a larger size.
321 #
322
323 proc Pad { } {
324 global theimg
325 global helv12
326 global datatype
327 set bkg [Bimage get $theimg background]
328 set w .pad
329 catch {destroy $w}
330 toplevel $w
331 wm title $w "Pad image"
332 wm iconname $w "Pad"
333
334 label $w.msg -font $helv12 -wraplength 4i -justify left \
335 -text {Setting these options modify the internal image on selecting OK}
336 pack $w.msg -side top -padx 5 -pady 5
337
338 # set filltype 2
339
340 frame $w.fill
341 label $w.fill.tag -font $helv12 -text "Fill type" -width 12
342 radiobutton $w.fill.avg -text "Average" -variable filltype -value 1
343 radiobutton $w.fill.back -text "Background" -variable filltype -value 2
344 radiobutton $w.fill.val -text "Value" -variable filltype -value 0
345 entry $w.fill.entry -width 6 -validate key -vcmd { string is double %P }
346 $w.fill.entry insert 0 $bkg
347 $w.fill.back select
348 pack $w.fill.tag $w.fill.avg $w.fill.back $w.fill.val \
349 $w.fill.entry -side left -fill both -expand true
350
351 set start "0 0 0"
352 set end "0 0 0"
353
354 setupSizeEntry $w.start "Translation" int $start "Translation in pixels (can be negative)"
355 setupSizeEntry $w.end "Size" int $end "Final size in pixels"
356 pack $w.start $w.end $w.fill -side top -padx 5 -pady 5
357
358 frame $w.buttons
359 button $w.buttons.ok -text OK -command "padImage $w"
360 button $w.buttons.cancel -text Cancel -command "destroy $w"
361
362 pack $w.buttons -side bottom -fill x -pady 2m
363 pack $w.buttons.ok $w.buttons.cancel -side left -expand 1
364
365 bind $w <Return> "padImage $w"
366 }
367
368 ## @brief Pads the image.
369 #
370 # @param w the window to destroy.
371
372 proc padImage { w } {
373 global theimg
374 global filltype
375 set xm [$w.start.x get]
376 set xp [$w.end.x get]
377 set ym [$w.start.y get]
378 set yp [$w.end.y get]
379 set zm [$w.start.z get]
380 set zp [$w.end.z get]
381 set fill [$w.fill.entry get]
382 destroy $w
383 Bimage pad $theimg $xm $ym $zm $xp $yp $zp $filltype $fill
384 reconfigureScales
385 Update 1
386 }
387
388 ## @brief Invokes a dialog box with modifyable image parameters.
389 #
390
391 proc modifyImage { } {
392 global theimg
393 global helv12
394 global datatype
395 set datatype [Bimage get $theimg datatype]
396 set origin [Bimage get $theimg origin]
397 set nimages [Bimage get $theimg nimages]
398 set nslices [Bimage get $theimg nslices]
399 set w .mod
400 catch {destroy $w}
401 toplevel $w
402 wm title $w "Modify image"
403 wm iconname $w "Modify"
404
405 label $w.msg -font $helv12 -wraplength 4i -justify left \
406 -text {Setting these options modify the internal image on selecting OK}
407
408 frame $w.panel
409 frame $w.panel.datatype
410 label $w.panel.datatype.tag -text "Data type"
411 tk_optionMenu $w.panel.datatype.menu datatype "unknown" "unsigned char (byte)" \
412 "signed char" "unsigned short" "short" "unsigned int" "int" \
413 "unsigned long" "long" "float" "double"
414
415 frame $w.panel.origin
416 label $w.panel.origin.tag -font $helv12 -text "Origin"
417 entry $w.panel.origin.entryx -width 6 -validate key -vcmd { string is double %P }
418 entry $w.panel.origin.entryy -width 6 -validate key -vcmd { string is double %P }
419 entry $w.panel.origin.entryz -width 6 -validate key -vcmd { string is double %P }
420 $w.panel.origin.entryx insert 0 [lindex $origin 0]
421 $w.panel.origin.entryy insert 0 [lindex $origin 1]
422 $w.panel.origin.entryz insert 0 [lindex $origin 2]
423
424 frame $w.panel.reslice
425 label $w.panel.reslice.tag -font $helv12 -text "Reslice"
426 entry $w.panel.reslice.entry -width 10
427 $w.panel.reslice.entry insert 0 "xyz"
428
429 frame $w.panel.rotate
430 label $w.panel.rotate.tagpsi -font $helv12 -text "Rotate: psi"
431 label $w.panel.rotate.tagtheta -font $helv12 -text "theta"
432 label $w.panel.rotate.tagphi -font $helv12 -text "phi"
433 entry $w.panel.rotate.entrypsi -width 4 -validate key -vcmd { string is double %P }
434 entry $w.panel.rotate.entrytheta -width 4 -validate key -vcmd { string is double %P }
435 entry $w.panel.rotate.entryphi -width 4 -validate key -vcmd { string is double %P }
436 $w.panel.rotate.entrypsi insert 0 "0"
437 $w.panel.rotate.entrytheta insert 0 "0"
438 $w.panel.rotate.entryphi insert 0 "0"
439
440 frame $w.panel.truncate
441 label $w.panel.truncate.tagmin -font $helv12 -text "Truncate: min"
442 label $w.panel.truncate.tagmax -font $helv12 -text "max"
443 entry $w.panel.truncate.entrymin -width 6 -validate key -vcmd { string is double %P }
444 entry $w.panel.truncate.entrymax -width 6 -validate key -vcmd { string is double %P }
445 $w.panel.truncate.entrymin insert 0 [Bimage get $theimg min]
446 $w.panel.truncate.entrymax insert 0 [Bimage get $theimg max]
447
448 frame $w.panel.rescale
449 label $w.panel.rescale.tagavg -font $helv12 -text "Rescale: avg"
450 label $w.panel.rescale.tagstd -font $helv12 -text "std"
451 entry $w.panel.rescale.entryavg -width 6 -validate key -vcmd { string is double %P }
452 entry $w.panel.rescale.entrystd -width 6 -validate key -vcmd { string is double %P }
453 $w.panel.rescale.entryavg insert 0 [Bimage get $theimg average]
454 $w.panel.rescale.entrystd insert 0 [Bimage get $theimg standard_deviation]
455
456 frame $w.buttons
457 button $w.buttons.ok -text OK -command "modifyImage_and_DestroyWindow $w"
458 button $w.buttons.cancel -text Cancel -command "destroy $w"
459
460 pack $w.msg -side top -padx 5 -pady 5
461 pack $w.panel -side top -fill both
462 pack $w.panel.datatype $w.panel.origin $w.panel.reslice $w.panel.rotate \
463 $w.panel.truncate $w.panel.rescale -side top -fill both
464
465 pack $w.panel.datatype.tag $w.panel.datatype.menu \
466 -side left -padx 5 -pady 5
467 pack $w.panel.origin.tag $w.panel.origin.entryx $w.panel.origin.entryy \
468 $w.panel.origin.entryz -side left -padx 5 -pady 5
469 pack $w.panel.reslice.tag $w.panel.reslice.entry -side left -padx 5 -pady 5
470 pack $w.panel.rotate.tagpsi $w.panel.rotate.entrypsi $w.panel.rotate.tagtheta \
471 $w.panel.rotate.entrytheta $w.panel.rotate.tagphi $w.panel.rotate.entryphi \
472 -side left -padx 5 -pady 5
473 pack $w.panel.truncate.tagmin $w.panel.truncate.entrymin \
474 $w.panel.truncate.tagmax $w.panel.truncate.entrymax -side left -padx 5 -pady 5
475 pack $w.panel.rescale.tagavg $w.panel.rescale.entryavg \
476 $w.panel.rescale.tagstd $w.panel.rescale.entrystd -side left -padx 5 -pady 5
477 pack $w.buttons -side bottom -fill x -pady 2m
478 pack $w.buttons.ok $w.buttons.cancel -side left -expand 1
479
480 bind $w <Return> "modifyImage_and_DestroyWindow $w"
481 }
482
483 ## @brief Modifies the image.
484 #
485 # @param w the window to destroy.
486
487 proc modifyImage_and_DestroyWindow { w } {
488 global theimg
489 global datatype project_item
490 set do_trunc 0
491 set do_rescale 0
492 set ox [$w.panel.origin.entryx get]
493 set oy [$w.panel.origin.entryy get]
494 set oz [$w.panel.origin.entryz get]
495 set order [$w.panel.reslice.entry get]
496 set psi [$w.panel.rotate.entrypsi get]
497 set theta [$w.panel.rotate.entrytheta get]
498 set phi [$w.panel.rotate.entryphi get]
499 set min [$w.panel.truncate.entrymin get]
500 set max [$w.panel.truncate.entrymax get]
501 if { [expr abs($min - [Bimage get $theimg min])] > 0.001 \
502 || [expr abs($max - [Bimage get $theimg max])] > 0.001 } {
503 set do_trunc 1
504 }
505 set avg [$w.panel.rescale.entryavg get]
506 set std [$w.panel.rescale.entrystd get]
507 if { [expr abs($avg - [Bimage get $theimg average])] > 0.001 \
508 || [expr abs($std - [Bimage get $theimg standard_deviation])] > 0.001 } {
509 set do_rescale 1
510 }
511 destroy $w
512 Bimage set $theimg origin $ox $oy $oz
513 if [Bmg exists] { Bmg set $project_item origin $ox $oy $oz}
514 Bimage reslice $theimg $order
515 Bimage rotate $theimg $psi $theta $phi
516 if { $do_trunc } {
517 Bimage truncate $theimg $min $max
518 }
519 if { $do_rescale } {
520 Bimage rescale $theimg $avg $std
521 }
522 set olddatatype [Bimage get $theimg datatype]
523 if { $datatype != $olddatatype } {
524 Bimage set $theimg datatype $datatype
525 }
526 Update 1
527 reconfigureScales
528 }
529
530 ## @brief This chnages the data type.
531 #
532
533 proc changeDataType { datatype } {
534 global theimg
535 set olddatatype [Bimage get $theimg datatype]
536 if { $datatype != $olddatatype } {
537 Bimage set $theimg datatype $datatype
538 }
539 Update 1
540 reconfigureScales
541 }
542
543 ## @brief This inverts the image.
544 #
545
546 proc invertImage {} {
547 global theimg
548 Bimage invert $theimg
549 Update 1
550 reconfigureScales
551 }
552
553 ## @brief This invokes a dialog box with binning parameters.
554 #
555
556 proc Bin {} {
557 global theimg
558 global helv12
559
560 set w .wbin
561 catch {destroy $w}
562 toplevel $w
563 wm title $w "Bin image"
564 wm iconname $w "Bin"
565
566 set bin "1 1 1"
567
568 label $w.msg -justify left \
569 -text {Setting these options modify the internal image on selecting OK}
570 pack $w.msg -side top -padx 5 -pady 5
571
572 setupSizeEntry $w.bin "Binning" int $bin "The level of binning"
573
574 frame $w.buttons
575 button $w.buttons.ok -text OK -command "binImage $w"
576 button $w.buttons.cancel -text Cancel -command "destroy $w"
577 pack $w.buttons.ok $w.buttons.cancel -side left -expand 1
578
579 pack $w.msg $w.bin $w.buttons -side top -pady 2m
580
581 bind $w <Return> "binImage $w"
582 }
583
584 ## @brief This inverts the image.
585 #
586
587 proc binImage { w } {
588 global theimg
589 set bx [$w.bin.x get]
590 set by [$w.bin.y get]
591 set bz [$w.bin.z get]
592 destroy $w
593 Bimage bin $theimg $bx $by $bz
594 Update 1
595 set pixel_size [Bimage get $theimg pixel_size]
596 if $pixel_size {
597 set wc [getControlWindow $theimg]
598 $wc.pixel_size.entry delete 0 end
599 $wc.pixel_size.entry insert 0 $pixel_size
600 }
601 reconfigureScales
602 }
603
604 ## @brief This invokes a dialog box with filter parameters.
605 #
606
607 proc Filter {} {
608 global theimg filter_type
609 global helv12 kernel avg_check
610
611 set w .wfilt
612 catch {destroy $w}
613 toplevel $w
614 wm title $w "Filter image"
615 wm iconname $w "Filter"
616
617 label $w.msg -justify left \
618 -text {Setting these options modify the internal image on selecting OK}
619 pack $w.msg -side top -padx 5 -pady 5
620
621 frame $w.type
622 label $w.type.l -font $helv12 -text "Type" -bg orange
623 tk_optionMenu $w.type.opt filter_type "Averaging" "Variance" "Normalizing" "Gaussian"
624 pack $w.type.l $w.type.opt -side left -ipadx 2
625
626 setupEntry $w.kernel "Kernel" integer $kernel "The size of the filter kernel"
627
628 frame $w.buttons
629 button $w.buttons.pref -text "Set preference" -command { set avg_check 1 }
630 button $w.buttons.ok -text Filter -command "filterImage $w"
631 button $w.buttons.cancel -text Cancel -command "destroy $w"
632 pack $w.buttons.pref $w.buttons.ok $w.buttons.cancel -side left -expand 1
633
634 pack $w.msg $w.type $w.kernel $w.buttons -side top -pady 2m
635
636 bind $w <Return> "filterImage $w"
637 }
638
639 ## @brief This filters the image.
640 #
641
642 proc filterImage { w } {
643 global theimg filter_type kernel
644 set kernel [$w.kernel.e get]
645 destroy $w
646 if { [string compare $filter_type "Averaging"] == 0 } {
647 Bimage average $theimg $kernel $kernel $kernel
648 } elseif { [string compare $filter_type "Variance"] == 0 } {
649 Bimage variance $theimg $kernel $kernel $kernel
650 } elseif { [string compare $filter_type "Normalizing"] == 0 } {
651 Bimage normalize $theimg $kernel $kernel $kernel
652 } elseif { [string compare $filter_type "Gaussian"] == 0 } {
653 set sigma [expr $kernel/6.0]
654 puts "Gaussian filter: $sigma"
655 Bimage gaussian $theimg $kernel $sigma
656 }
657 Update 1
658 reconfigureScales
659 }
660
661 ## @brief This invokes a dialog box with montage parameters.
662 #
663
664 proc Montage {} {
665 global theimg
666 global helv12 font_size selected_color
667 global flipx flipy
668 set bkg [Bimage get $theimg background]
669 set w .wmont
670 catch {destroy $w}
671 toplevel $w
672 wm title $w "Montage image"
673 wm iconname $w "Montage"
674
675 label $w.msg -font $helv12 -wraplength 4i -justify left \
676 -text {Setting these options modify the internal image on selecting OK}
677 pack $w.msg -side top -padx 5 -pady 5
678
679 setupEntry $w.col "Columns" integer 0 "Number of columns"
680 setupEntry $w.row "Rows" integer 0 "Number of rows"
681 setupEntry $w.first "First panel" integer 0 "First image or slice to start from"
682 setupEntry $w.skip "Skip" integer 0 "Number of images or slices to skip between panels"
683 setupEntry $w.pad "Padding" integer 0 "Amount of padding between panels"
684 setupEntry $w.fill "Fill value" double $bkg "User-defined fill value between panels"
685 frame $w.flip
686 checkbutton $w.flip.x -text "Flip X" -variable flipx
687 checkbutton $w.flip.y -text "Y" -variable flipy
688 pack $w.flip.x $w.flip.y -side left
689 pack $w.col $w.row $w.first $w.skip $w.pad \
690 $w.fill $w.flip -side top -padx 5 -pady 5
691
692 frame $w.switches
693 label $w.switches.tag -text "Show:"
694 checkbutton $w.switches.boxes -text "Boxes" -variable show_mont \
695 -command { drawMontageOverlay }
696 checkbutton $w.switches.labels -text "Labels" -variable show_mont_labels \
697 -command { drawMontageOverlay }
698 checkbutton $w.switches.select -text "Selection" -variable show_mont_select \
699 -command { drawMontageOverlay }
700 pack $w.switches.tag $w.switches.boxes $w.switches.labels $w.switches.select \
701 -side left -ipadx 5 -ipady 5 -padx 1m
702
703 frame $w.font
704 label $w.font.tag -font $helv12 -text "Font size:"
705 tk_optionMenu $w.font.size font_size "12" "18" "24" "32" "40"
706 canvas $w.font.color -width 30 -height 30 -relief sunken \
707 -borderwidth 2 -background $selected_color
708 pack $w.font.tag $w.font.size $w.font.color -side left -ipadx 5 -ipady 5 -padx 1m
709
710 frame $w.buttons
711 button $w.buttons.ok -text Montage -command "montageImage $w"
712 button $w.buttons.cancel -text Unset -command "unsetMontage"
713 button $w.buttons.save -text Save -command "saveMontage"
714 button $w.buttons.del -text "Delete selected" -command "deleteMontageSelection"
715 pack $w.buttons.ok $w.buttons.cancel $w.buttons.save $w.buttons.del -side left -expand 1
716
717 pack $w.switches $w.font $w.buttons -side top -fill x -pady 2m
718
719 bind $w.font.color <1> { selectColor .wmont.font.color }
720 bind $w <Return> "montageImage $w"
721 }
722
723 ## @brief Montages the image.
724 #
725
726 proc montageImage { w } {
727 global theimg
728 global flipx flipy montover font_size selected_color
729 set first [$w.first.e get]
730 set ncol [$w.col.e get]
731 set nrow [$w.row.e get]
732 set skip [$w.skip.e get]
733 set pad [$w.pad.e get]
734 set fill [$w.fill.e get]
735 set flip [expr $flipx + 2 * $flipy]
736 set nx [Bimage get $theimg width]
737 set ny [Bimage get $theimg height]
738 Bimage set $theimg montage $ncol $nrow $first $skip $pad $fill $flip
739 set montover(active) 1
740 set montover(nx) $nx
741 set montover(ny) $ny
742 set montover(ncol) $ncol
743 set montover(nrow) $nrow
744 set montover(first) $first
745 set montover(skip) $skip
746 set montover(pad) $pad
747 set montover(flip) $flip
748 set montover(fontsize) $font_size
749 set montover(fontcolor) $selected_color
750 reconfigureScales
751 Update 1
752 }
753
754 proc unsetMontage { } {
755 global theimg montover
756 set c [getImageCanvas $theimg]
757 $c delete mont
758 set montover(active) 0
759 Bimage set $theimg montage 0 0
760 reconfigureScales
761 Update 1
762 }
763
764 proc drawMontageOverlay { } {
765 global theimg
766 global flipx flipy montover show_mont show_mont_labels show_mont_select
767 set c [getImageCanvas $theimg]
768 $c delete mont
769 if { $montover(active) < 1 } { return}
770 if { $montover(nx) < 1 } { return}
771 if { $montover(ny) < 1 } { return}
772 # puts Overlay
773 set nimg [Bimage get $theimg nimages]
774 set scale [.scale.scale get]
775 set nx [expr $scale * $montover(nx)]
776 set ny [expr $scale * $montover(ny)]
777 set first $montover(first)
778 set skip $montover(skip)
779 set ncol $montover(ncol)
780 set nrow $montover(nrow)
781 set pad [expr $scale * $montover(pad)]
782 if { $flipy } {
783 set ymin [expr $pad + $ny]
784 } else {
785 set ymin [expr $pad * (2 * $nrow - 1) + $ny * $nrow]
786 }
787 set i $first
788 set show_mont_font [list "Helvetica" $montover(fontsize) "bold"]
789 # puts $show_mont_font
790 for { set row 0} { $row < $nrow } { incr row 1} {
791 set ymax [expr $ymin - $ny + 1]
792 if { $flipx } {
793 set xmin [expr $nx * ($ncol - 1) + $pad * (2 * $ncol - 1)]
794 } else {
795 set xmin $pad
796 }
797 for { set col 0} { $col < $ncol } { incr col 1} {
798 set xmax [expr $xmin + $nx - 1]
799 # puts "$xmin $ymin $xmax $ymax"
800 set xt [expr $xmin + 5]
801 set yt [expr $ymin - 3]
802 set sel [array get montover "$col,$row"]
803 if [llength $sel] {
804 set color red
805 } else {
806 set color yellow
807 }
808 if $show_mont {
809 $c create rect $xmin $ymin $xmax $ymax -outline $color \
810 -width 1 -tags mont
811 }
812 if { $i < $nimg } {
813 if $show_mont_labels {
814 $c create text $xt $yt -text $i -anchor sw -fill $color \
815 -font $show_mont_font -tags mont
816 }
817 set xt [expr $xmax - 5]
818 if $show_mont_select {
819 set img_sel [Bimage get $theimg select $i]
820 $c create text $xt $yt -text $img_sel -anchor se \
821 -fill $montover(fontcolor) -font $show_mont_font -tags mont
822 }
823 }
824 if { $flipx } {
825 set xmin [expr $xmin - $nx - 2 * $pad]
826 } else {
827 set xmin [expr $xmin + $nx + 2 * $pad]
828 }
829 set i [expr $i + $skip + 1]
830 }
831 if { $flipy } {
832 set ymin [expr $ymin + $ny + 2 * $pad]
833 } else {
834 set ymin [expr $ymin - $ny - 2 * $pad]
835 }
836 }
837 bind $c <1> "montageSelect %x %y"
838 bind . <Key-o> { saveMontageSelection }
839 }
840
841 proc montageSelect { x y } {
842 global flipx flipy montover
843 set scale [.scale.scale get]
844 set nx [expr $scale * $montover(nx)]
845 set ny [expr $scale * $montover(ny)]
846 set ncol $montover(ncol)
847 set nrow $montover(nrow)
848 set pad [expr $scale * $montover(pad)]
849 if { $flipx } {
850 set col [expr $ncol - int($x/($nx + 2 * $pad)) - 1]
851 } else {
852 set col [expr int($x/($nx + 2 * $pad))]
853 }
854 if { $flipy } {
855 set row [expr int($y/($ny + 2 * $pad))]
856 } else {
857 set row [expr $nrow - int($y/($ny + 2 * $pad)) - 1]
858 }
859 set sel [array get montover "$col,$row"]
860 if [llength $sel] {
861 unset montover($col,$row)
862 } else {
863 set montover($col,$row) 1
864 }
865 # puts "$col $row"
866 # foreach key [array names montover "*,*"] {
867 # puts "$key $montover($key)"
868 # }
869 drawMontageOverlay
870 }
871
872 proc saveMontage { } {
873 global theimg montover
874 global imgdir filename
875 global filetypes
876 set currdir $imgdir
877 if { [string length $currdir] < 2 } { set currdir [pwd]}
878 set new_filename [tk_getSaveFile -filetypes $filetypes \
879 -initialfile [file tail $filename] -initialdir $currdir \
880 -defaultextension .pif]
881 if { [string length $new_filename] < 1 } { return}
882 set new_filename [relativePath [pwd] $new_filename]
883 Bimage save_montage $theimg $new_filename
884 }
885
886 proc saveMontageSelection { } {
887 global montover
888 set w .wtxt
889 set wt [openTextWindow $w]
890 set first $montover(first)
891 set skip $montover(skip)
892 set ncol $montover(ncol)
893 foreach key [array names montover "*,*"] {
894 # puts "$key $montover($key)"
895 set coor [split $key ,]
896 set col [lindex $coor 0]
897 set row [lindex $coor 1]
898 set i [expr $first + $ncol * $row + $col]
899 # $wt insert end "$col\t$row\t$i\n"
900 $wt insert end "$i\n"
901 }
902 saveAsTextFile $wt
903 }
904
905 proc deleteMontageSelection { } {
906 global montover theimg
907 set first $montover(first)
908 set skip $montover(skip)
909 set ncol $montover(ncol)
910 set delist ""
911 foreach key [array names montover "*,*"] {
912 # puts "$key $montover($key)"
913 set coor [split $key ,]
914 set col [lindex $coor 0]
915 set row [lindex $coor 1]
916 set i [expr $first + $ncol * $row + $col]
917 if [string length $delist] {
918 append delist ",$i"
919 } else {
920 append delist $i
921 }
922 unset montover($key)
923 }
924 # puts $delist
925 Bimage delete $theimg $delist
926 reconfigureScales
927 Update 1
928 }
929
930 ## @brief Calculates a Fourier transform of the image data.
931 #
932
933 proc FourierTransform { dir } {
934 global theimg
935 global imgtype
936 Bimage fft $theimg $dir
937 if { $dir < 0 } {
938 set imgtype "ft"
939 } else {
940 set imgtype ""
941 }
942 reconfigureScales
943 .scale.scale set 1.0
944 }
945
946 ## @brief Calculates a power spectrum of the image data.
947 #
948
949 proc PowerSpectrum { } {
950 global theimg project_item
951 global helv12
952 global lg avgtileps avgframeps tiled
953 global tilex tiley tilez
954 global tilt_axis tilt_angle tilt_offset defocus
955
956 set nx [Bimage get $theimg width]
957 set ny [Bimage get $theimg height]
958 set nz [Bimage get $theimg nslices]
959 if { $tilex > $nx } { set tilex $nx}
960 if { $tiley > $ny } { set tiley $ny}
961 if { $tilez > $nz } { set tilez $nz}
962
963 set tilesize "$tilex $tiley $tilez"
964 set cs 2.0
965 set volt 300
966
967 if [Bmg exists] {
968 set defocus [Bmg get $project_item defocus]
969 set tilt_axis [Bmg get $project_item axis]
970 set tilt_angle [Bmg get $project_item tilt]
971 set cs [Bmg get $project_item Cs]
972 set volt [Bmg get $project_item volt]
973 }
974
975 # puts "$cs $volt"
976
977 set w .wps
978 catch {destroy $w}
979 toplevel $w
980 wm title $w "Power spectrum"
981 wm iconname $w "PS"
982
983 label $w.msg -font $helv12 -wraplength 4i -justify left \
984 -text {Select parameters to calculate a power spectrum}
985 pack $w.msg -side top -padx 5 -pady 5
986
987 checkbutton $w.logbutton -text "Logarithm" -variable lg
988 checkbutton $w.avgtiles -text "Average tile power spectra" -variable avgtileps
989 checkbutton $w.avgframes -text "Average frame power spectra" -variable avgframeps
990
991 setupCheckSizeEntry $w.tiles "Tiles" int $tilesize tiled "Size of tiles to divide the micrograph"
992
993 labelframe $w.tilt -text "Tilt parameters"
994 setupEntry $w.tilt.axis "Tilt axis angle" double $tilt_axis "Micrograph tilt axis angle conter-clockwise from the x-axis in degrees"
995 setupEntry $w.tilt.angle "Tilt angle" double $tilt_angle "Micrograph tilt angle in degrees"
996 setupEntry $w.tilt.offset "Offset from origin" double $tilt_offset "Tilt axis offset from the micrograph origin"
997 setupEntry $w.tilt.defocus "Defocus" double $defocus "Estimate/guess of defocus"
998 setupEntry $w.tilt.cs "Spherical aberration" double $cs "Cs in mm"
999 setupEntry $w.tilt.volt "Acceleration voltage" double $volt "Acceleration voltage in kV"
1000 pack $w.tilt.axis $w.tilt.angle $w.tilt.offset $w.tilt.defocus \
1001 $w.tilt.cs $w.tilt.volt -side top -expand 1
1002
1003 frame $w.buttons
1004 button $w.buttons.ok -text OK -command "calcPowerSpec $w"
1005 button $w.buttons.cancel -text Cancel -command "destroy $w"
1006 pack $w.buttons.ok $w.buttons.cancel -side left -expand 1
1007
1008 pack $w.logbutton $w.avgframes $w.avgtiles $w.tiles $w.tilt $w.buttons -side top
1009
1010 bind $w <Return> "calcPowerSpec $w"
1011 }
1012
1013 ## @brief Calculates a power spectrum of the image data.
1014 #
1015 # @param w the window to destroy.
1016
1017 proc calcPowerSpec {w} {
1018 global theimg
1019 global lg avgtileps avgframeps tiled
1020 global tilex tiley tilez
1021 global tilt_axis tilt_angle tilt_offset defocus
1022 global imgtype
1023 global filename project_item
1024 global window_width window_scale
1025
1026 set tilex [$w.tiles.x get]
1027 set tiley [$w.tiles.y get]
1028 set tilez [$w.tiles.z get]
1029 set tilt_axis [$w.tilt.axis.e get]
1030 set tilt_angle [$w.tilt.angle.e get]
1031 set tilt_offset [$w.tilt.offset.e get]
1032 set defocus [$w.tilt.defocus.e get]
1033 set cs [$w.tilt.cs.e get]
1034 set volt [$w.tilt.volt.e get]
1035 if { $tilt_angle != 0 } { set tiled 1}
1036 destroy $w
1037 # puts "Powerspectrum: $lg $tiled"
1038 set flags [expr 1 + 2*$avgtileps + 4 + 8*$lg + 16*$avgframeps]
1039 if $tiled {
1040 Bimage powerspec $theimg $flags $tilex $tiley $tilez $tilt_axis $tilt_angle $tilt_offset $defocus $cs $volt
1041 } else {
1042 Bimage powerspec $theimg $flags
1043 }
1044 set imgtype "ps"
1045 if [Bmg exists] {
1046 setMgParam
1047 Bmg set $project_item filename $filename ps
1048 Bmg set $project_item axis [expr $tilt_axis]
1049 Bmg set $project_item tilt [expr $tilt_angle]
1050 }
1051 reconfigureRangeStep
1052 reconfigureScales
1053 set scale 1.0
1054 set width [Bimage get $theimg width]
1055 if { $width > $window_width } { set scale [expr 0.1*((10*$window_width)/$width)]}
1056 if { $scale < 0.1 } { set scale 0.1}
1057 set window_scale $scale
1058 .scale.scale set $scale
1059 set ps [Bimage get $theimg pixel_size]
1060 puts "Power spectrum pixel size: $ps"
1061 }
1062