source: trunk/odf.tcl

Last change on this file was 1251, checked in by toby, 9 years ago

use svn ps svn:eol-style "native" * to change line ends

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Revision Id
File size: 13.1 KB
Line 
1# $Id: odf.tcl 1251 2014-03-10 22:17:29Z toby $
2
3# Convert a Laue code as used in SPACEGRP to a number, as used in odfchk
4proc LaueCode2number {laueaxis} {
5    switch -exact $laueaxis {
6        1bar {return 1}
7        2/ma -
8        2/mb -
9        2/mc {return 2}
10        mmm  {return 3}
11        4/{return 4}
12        4/mmm {return 5}
13        3barR     {return 6}
14        "3bar mR" {return 7}
15        3bar    {return 8} 
16        3barm1 {return 9}
17        3bar1m  {return 10}
18        6/m    {return 11}
19        6/mmm  {return 12}
20        "m 3"  {return 13}
21        m3m    {return 14}
22        default {return ""}
23    }
24}
25
26# computes a list of ODF (l,m,n) terms for a given spherical harmonic order,
27#   sample symmetry and Laue symmetry
28proc ComputeODFterms {order ISAMSYM laueaxis} {
29
30    set laue [LaueCode2number $laueaxis]
31
32    set odflist {}
33    set ITOT 0
34    for {set I 2} {$I <= $order} {incr I 2} {
35        for {set M -$I} {$M <= $I} {incr M 1} {
36            if {[odfchk $ISAMSYM $I $M]} {
37                for {set N -$I} {$N <= $I} {incr N 1} {
38                    if {[odfchk $laue $I $N]} {
39                        incr ITOT
40                        lappend odflist [list $I $M $N]
41                    }
42                }
43            }
44        }
45    }
46    return $odflist
47}
48
49#PURPOSE: To determine if spherical harmonic term C(l,m) is allowed
50#   in LAUE group
51# based on GSAS FUNCTION ODFCHK(LAUE,L,M)
52proc odfchk {laue l m} {
53
54    set ODFCHK 0
55    if { $l % 2 == 0 && abs($m) <= $l } {
56        if { $laue == 0 } {
57            #Cylindricaly symmetric
58            if { $m == 0 } {set ODFCHK 1}
59        } elseif { $laue == 1 } {
60            #1-bar
61            set ODFCHK 1
62        } elseif { $laue == 2 } {
63            #2/m
64            if { abs($m) % 2 == 0 } {set ODFCHK 1}
65        } elseif { $laue == 3 } {
66            #mmm
67            if { abs($m) % 2 == 0 && $m >= 0 } {set ODFCHK 1}
68        } elseif { $laue == 4 } {
69            #4/m
70            if { abs($m) % 4 == 0 } {set ODFCHK 1}
71        } elseif { $laue == 5 } {
72            #4/mmm
73            if { abs($m) % 4 == 0 && $m >= 0 } {set ODFCHK 1}
74        } elseif { $laue == 6 } {
75            #R-3 R
76            if { abs($m) % 3 == 0 } {set ODFCHK 1}
77        } elseif { $laue == 7 } {
78            #R-3m R
79            if { abs($m) % 3 == 0 && $m >= 0 } {set ODFCHK 1}
80        } elseif { $laue == 8 } {
81            #-3
82            if { abs($m) % 3 == 0 } {set ODFCHK 1}
83        } elseif { $laue == 9 } {
84            #-3m1
85            if { abs($m) % 3 == 0 && $m >= 0 } {set ODFCHK 1}
86        } elseif { $laue == 10 } {
87            #-31m
88            if { abs($m) % 3 == 0 && $m >= 0 } {set ODFCHK 1}
89        } elseif { $laue == 11 } {
90            #6/m
91            if { abs($m) % 6 == 0 } {set ODFCHK 1}
92        } elseif { $laue == 12 } {
93            #6/mmm
94            if { abs($m) % 6 == 0 && $m >= 0 } {set ODFCHK 1}
95        } elseif { $laue == 13 } {
96            #m3
97            if { $m > 0 } {
98                if { $l % 12 == 2 } {
99                    if {$m <= ($l/12) } {set ODFCHK 1}
100                } else {
101                    if {$m <= ($l/12+1) } {set ODFCHK 1}
102                }
103            }
104        } elseif { $laue == 14 } {
105            #m3m
106            if { $m > 0 } {
107                if { $l % 12 == 2 } {
108                    if {$m <= ($l/12) } {set ODFCHK 1}
109                } else {
110                    if {$m <= ($l/12+1) } {set ODFCHK 1}
111                }
112            }
113        }
114    }
115    return $ODFCHK
116}
117
118# called once to make the ODF (spherical harmonics) pane
119# this gets done the first time the pane is selected
120proc MakeODFPane {} {
121    global expgui entryvar entrycmd entrybox
122    pack [TitleFrame $expgui(odfFrame).f1 -bd 4 \
123              -text "Spherical Harmonic (ODF) Preferential Orientation" \
124              -relief groove] -side top -expand yes -fill x -anchor n
125    set expgui(odfFrameTop) [$expgui(odfFrame).f1 getframe]
126
127    grid [frame  $expgui(odfFrameTop).ps] -column 0 -row 0 -sticky w
128    # this is where the buttons will go
129    pack [label $expgui(odfFrameTop).ps.0 -text "No Phases"] -side left
130   
131    grid [label $expgui(odfFrameTop).lA -text " title:" \
132            -fg blue ] -column 1 -row 0 -sticky e
133    grid columnconfig $expgui(odfFrameTop) 1 -weight 1
134    grid [entry $expgui(odfFrameTop).lB -textvariable entryvar(phasename) \
135            -fg blue -width 45] -column 2 -columnspan 10 -row 0 -sticky e
136    grid columnconfigure $expgui(odfFrameTop) 1 -weight 1
137
138    set row 1
139    set angframe [frame $expgui(odfFrameTop).ang]
140    grid $angframe -row 2 -column 0 -columnspan 10
141    grid [label $angframe.l -text "Setting\nangles: "] \
142            -column 0 -row $row
143    foreach col {1 4 7} var {omega chi phi} lbl {w c f} {
144        grid [label $angframe.l$var -text $lbl] \
145                -column $col -row $row -padx 5 -sticky e
146        set font [$angframe.l$var cget -font]
147        $angframe.l$var config -font "Symbol [lrange $font 1 end]"
148        incr col
149        grid [checkbutton $angframe.r$var \
150                -variable entryvar(ODF${var}Ref)] \
151                -column $col -row $row 
152        incr col
153        grid [entry $angframe.e$var \
154                -textvariable entryvar(ODF$var) -width 10] \
155                -column $col -row $row -padx 5
156        set entrybox(ODF$var) $angframe.e$var
157    }
158    grid [label $angframe.lDamp -text "Damping  "] \
159            -column [incr col] -row $row
160    tk_optionMenu $angframe.om entryvar(ODFdampA) 0 1 2 3 4 5 6 7 8 9
161    grid $angframe.om -column [incr col] -row $row
162
163    #
164    set ordframe [frame $expgui(odfFrameTop).ord]
165    grid $ordframe -row 1 -column 0 -columnspan 10
166    set col -1
167    grid [label $ordframe.lo -text "Spherical\nHarmonic Order: "] \
168            -column [incr col] -row $row
169    set ordmenu [tk_optionMenu $ordframe.ord expgui(ODForder) 0]
170    $ordmenu delete 0 end
171    for {set i 0} {$i <= 34} {incr i 2} {
172        $ordmenu insert end radiobutton -variable expgui(ODForder) \
173                -label $i -value $i -command SetODFTerms
174    }
175    $ordframe.ord config -width 3
176    grid $ordframe.ord -column [incr col] -row $row
177
178    grid [label $ordframe.ls -text "Sample\nsymmetry: "] \
179            -column [incr col] -row $row
180    set expgui(ODFsym) {}
181    set expgui(symmenu) [tk_optionMenu $ordframe.sym expgui(ODFsymLbl) \
182            Cylindrical None "Shear (2/m)" "Rolling (mmm)"]
183    grid $ordframe.sym -column [incr col] -row $row
184    for {set i 0} {$i <= [$expgui(symmenu) index end]} {incr i} {
185        $expgui(symmenu) entryconfigure $i -command "SetODFSym $i"
186    }
187    $ordframe.sym config -width 12
188    grid [label $ordframe.lr -text "Refine ODF\ncoefficients"] \
189                -column [incr col] -row $row -padx 5 -sticky e
190    grid [checkbutton $ordframe.r \
191                -variable entryvar(ODFRefcoef)] \
192                -column [incr col] -row $row 
193    grid [label $ordframe.lDamp -text "Damping  "] \
194            -column [incr col] -row $row
195    tk_optionMenu $ordframe.om entryvar(ODFdampC) 0 1 2 3 4 5 6 7 8 9
196    grid $ordframe.om -column [incr col] -row $row
197    pack [TitleFrame $expgui(odfFrame).f2 -bd 4 \
198              -text "Spherical Harmonic Terms: (l,m,n) & coeff's" \
199              -relief groove] -side top -fill both -expand yes -anchor n
200    set canvasfr [$expgui(odfFrame).f2 getframe]
201
202    set expgui(odfFrameCanvas) $canvasfr.canvas
203    set expgui(odfFrameScroll) $canvasfr.scroll
204    grid [canvas $expgui(odfFrameCanvas) \
205            -scrollregion {0 0 5000 500} -width 0 -height 250 \
206            -yscrollcommand "$expgui(odfFrameScroll) set"] \
207            -row 3 -column 0 -sticky ns
208    grid rowconfigure $expgui(odfFrameTop) 3 -weight 1
209    scrollbar $expgui(odfFrameScroll) \
210            -command "$expgui(odfFrameCanvas) yview"
211    frame $expgui(odfFrameCanvas).fr
212    $expgui(odfFrameCanvas) create window 0 0 -anchor nw -window $expgui(odfFrameCanvas).fr
213}
214
215proc SetODFSym {i} {
216    global expgui
217    if {$expgui(ODFsym) == $i} return
218    set expgui(ODFsym) $i
219    set expgui(ODForder) 0
220    SetODFTerms
221}
222
223proc SetODFTerms {} {
224    global expgui
225    if {$expgui(curPhase) == ""} return
226    set curterms [phaseinfo $expgui(curPhase) ODFterms]
227    set laueaxis [GetLaue [phaseinfo $expgui(curPhase) spacegroup]]
228    set newterms [ComputeODFterms $expgui(ODForder) $expgui(ODFsym) $laueaxis]
229    phaseinfo $expgui(curPhase) ODFterms set $newterms
230    RecordMacroEntry "phaseinfo $expgui(curPhase) ODFterms set $newterms" 0
231    phaseinfo $expgui(curPhase) ODForder set $expgui(ODForder)
232    RecordMacroEntry "phaseinfo $expgui(curPhase) ODForder set $expgui(ODForder)" 0
233    phaseinfo $expgui(curPhase) ODFsym set $expgui(ODFsym)
234    RecordMacroEntry "phaseinfo $expgui(curPhase) ODFsym set $expgui(ODFsym)" 0
235    # zero out the new terms
236    for {set i [expr [llength $curterms]+1]} \
237            {$i <= [llength $newterms]} {incr i} {
238        phaseinfo $expgui(curPhase) ODFcoef$i set 0.
239        RecordMacroEntry "phaseinfo $expgui(curPhase) ODFcoef$i set 0." 0
240    }
241    incr expgui(changed)
242    RecordMacroEntry "incr expgui(changed)" 0
243    SelectODFPhase $expgui(curPhase)
244}
245
246proc DisplayODFPane {} {
247    global expgui expmap
248    eval destroy [winfo children $expgui(odfFrameTop).ps]
249    pack [label $expgui(odfFrameTop).ps.0 -text Phase:] -side left
250    foreach num $expmap(phaselist) type $expmap(phasetype) {
251        pack [button $expgui(odfFrameTop).ps.$num -text $num \
252                -command "SelectODFPhase $num" -padx 1.5m] -side left
253        if {$type > 3} {
254            $expgui(odfFrameTop).ps.$num config -state disabled
255        }
256    }
257    # select the current phase
258    SelectODFPhase $expgui(curPhase)
259}
260
261# select a phase to display & display the ODF terms
262# called when pane is displayed (DisplayODFPane), a phase is selected using the
263# phase buttons or when the number of terms gets changed (SetODFTerms)
264# problem: this seems to be called multiple times -- for reasons that
265#          are unresolved -- but at least it's quick
266proc SelectODFPhase {num} {
267    global entryvar entrycmd entrybox expmap expgui
268    set crsPhase {}
269    # if no phase is selected, select the first phase
270    if {$num == ""} {set num [lindex $expmap(phaselist) 0]}
271    foreach n $expmap(phaselist) type $expmap(phasetype) {
272        if {$n == $num && $type <= 3} {
273            set crsPhase $num
274            catch {$expgui(odfFrameTop).ps.$num config -relief sunken}
275        } else { 
276            catch {$expgui(odfFrameTop).ps.$n config -relief raised}
277        }
278    }
279
280    # disable traces on entryvar until we are ready
281    set entrycmd(trace) 0
282
283    eval destroy [winfo children $expgui(odfFrameCanvas).fr]
284
285    if {$crsPhase == "" || [llength $expmap(phaselist)] == 0} {
286        # blank out the page
287        set expgui(ODFsymLbl) {}
288        set expgui(ODForder) {}
289        foreach var {omega chi phi omegaRef chiRef phiRef \
290                dampC dampA Refcoef} {
291            set entrycmd(ODF$var) {}
292            set entryvar(ODF$var) {}
293        }
294        set entryvar(phasename) {}
295        set entryvar(phasename) {}
296        grid forget $expgui(odfFrameScroll) 
297        set entrycmd(trace) 1
298        return
299    }
300    # phase name
301    set entrycmd(phasename) "phaseinfo $crsPhase name"
302    set entryvar(phasename) [phaseinfo $crsPhase name]
303    # ODFsym   -- sample symmetry (0-3) (*)
304    # prevent SetODFTerms from being run
305    set expgui(curPhase) {}
306    catch {$expgui(symmenu) invoke 0}
307    catch {$expgui(symmenu) invoke [phaseinfo $crsPhase ODFsym]}
308    set expgui(curPhase) $crsPhase
309    # ODForder -- spherical harmonic order (*)
310    set expgui(ODForder) [phaseinfo $expgui(curPhase) ODForder]
311    # ODFomega -- omega oriention angle (*)
312    # ODFchi -- chi oriention angle (*)
313    # ODFphi -- phi oriention angle (*)
314    # ODFomegaRef -- refinement flag for omega (*)
315    # ODFchiRef -- refinement flag for chi (*)
316    # ODFphiRef -- refinement flag for phi (*)
317    # ODFdampA -- damping for angles (*)
318    # ODFdampC -- damping for coefficients (*)
319    # ODFRefcoef -- refinement flag for ODF terms (*)
320    foreach var {omega chi phi omegaRef chiRef phiRef dampC dampA Refcoef} {
321        set entrycmd(ODF$var) "phaseinfo $expgui(curPhase) ODF$var"
322        set entryvar(ODF$var) [eval $entrycmd(ODF$var)]
323        # reset to black
324        catch {$entrybox(ODF$var) config -fg black}
325    }
326    #
327    set row 0
328    set term 0
329    set col 99
330    #     ODFterms -- a list of the {l m n} values for each ODF term (*)
331    #     ODFcoefXXX -- the ODF coefficient for for ODF term XXX (*)
332    set textureindex 1.0
333    foreach lmn [phaseinfo $expgui(curPhase) ODFterms] {
334        # make sure that numbers are separated by spaces
335        regsub -all -- "-" $lmn " -" lmn
336        incr term
337        if {$col > 5} {
338            incr row 2
339            grid rowconfig $expgui(odfFrameCanvas).fr $row \
340                    -minsize 2 -pad 10
341            set col 0
342        }
343        set lbl [eval format (%d,%d,%d) $lmn]
344        grid [label $expgui(odfFrameCanvas).fr.l$term -text $lbl] \
345                -column [incr col] -row $row -sticky s
346#       grid columnconfig $expgui(odfFrameCanvas).fr $col -pad 4
347        grid [entry $expgui(odfFrameCanvas).fr.e$term \
348                -width 10 -textvariable entryvar(ODFcoef$term)] \
349                -column $col -row [expr $row+1]
350        set entrycmd(ODFcoef$term) "phaseinfo $expgui(curPhase) ODFcoef$term"
351        set entryvar(ODFcoef$term) [eval $entrycmd(ODFcoef$term)]
352        set entrybox(ODFcoef$term) $expgui(odfFrameCanvas).fr.e$term
353        grid columnconfig $expgui(odfFrameCanvas).fr $col -pad 12
354        set textureindex [expr {$textureindex + \
355                ($entryvar(ODFcoef$term) * $entryvar(ODFcoef$term)) \
356                / ((2. * [lindex $lmn 0]) + 1.)}]
357    }
358
359    if {$term == 0} {
360        grid [label $expgui(odfFrameCanvas).fr.no -text "no terms" \
361                -anchor center] \
362                -column 0 -row 0 -sticky nsew
363    } else {
364        incr row 2
365        grid [label $expgui(odfFrameCanvas).fr.last \
366                -bd 2 -relief sunken -anchor center \
367                -text "Texture index = [format %.4f $textureindex]" ] \
368                -column 1 -columnspan 6 -row $row -sticky ew
369        grid rowconfig $expgui(odfFrameCanvas).fr $row -pad 12
370    }
371    # resize
372    update 
373    set sizes [grid bbox $expgui(odfFrameCanvas).fr]
374    set maxhgt 220
375    # use the scroll for BIG atom lists
376    if {[lindex $sizes 3] > $maxhgt} {
377        grid $expgui(odfFrameScroll) -sticky ns -column 1 -row 3
378        set height $maxhgt
379    } else {
380        grid forget $expgui(odfFrameScroll) 
381        set height [lindex $sizes 3]
382    }
383    $expgui(odfFrameCanvas) config -scrollregion $sizes \
384            -width [lindex $sizes 2] -height $height
385    set entrycmd(trace) 1
386}
387
388#debug code
389#set expgui(odfFrame) .test
390#catch {destroy $expgui(odfFrame)}
391#toplevel $expgui(odfFrame)
392#MakeODFPane
393#DisplayODFPane
Note: See TracBrowser for help on using the repository browser.