source: trunk/import_cif.tcl @ 1225

Last change on this file since 1225 was 1225, checked in by toby, 8 years ago

update to latest, with Fourier & f'/f

  • Property svn:keywords set to Author Date Revision Id
File size: 7.1 KB
Line 
1# $Id: import_cif.tcl 1225 2012-11-08 19:42:25Z toby $
2
3#-------------------------------------------------
4# define info used in addcmds.tcl
5catch {
6    # make sure vars get set at global level
7    global CIF
8    source [file join $expgui(scriptdir) browsecif.tcl]
9    set description "Crystallographic Information File (CIF)"
10    set extensions .cif
11    set procname ReadCIFFile
12}
13#-------------------------------------------------
14
15proc ReadCIFFile {filename} {
16    global expgui CIF
17    set fp [open $filename r]
18    pleasewait "Reading CIF file"         
19
20    catch {destroy [set file .file]}
21    toplevel $file
22    #bind $file <Key-F1> "MakeWWWHelp gsas2cif.html filltemplate"
23    set CIF(txt) $file.t
24    grid [text $CIF(txt) -height 10 -width 80 -yscrollcommand "$file.s set"] \
25            -column 0 -row 0 -sticky news
26    grid [scrollbar $file.s -command "$CIF(txt) yview"] \
27            -column 1 -row 0 -sticky ns
28    grid columnconfig $file 0 -weight 1
29    grid rowconfig $file 0 -weight 1
30    # hide it
31    wm withdraw $file
32    set blocks [ParseCIF $CIF(txt) $filename]
33    if {$blocks == ""} {
34        donewait
35        MyMessageBox -parent . -type ok -icon warning \
36                -message "Note: no valid CIF blocks were read from file $filename"
37        return 
38    }
39    set allblocks {}
40    set coordblocks {}
41    # search each block for coordinate
42    for {set i 1} {$i <= $blocks} {incr i} {
43        lappend allblocks $i
44        global block$i
45        set flag 1
46        foreach id {_atom_site_fract_x _atom_site_fract_y _atom_site_fract_z} {
47            if {[array name block$i $id] == ""} {set flag 0}
48        }
49        if $flag {lappend coordblocks $i}
50    }
51    donewait
52    if {$coordblocks == ""} {
53        MyMessageBox -parent . -type ok -icon warning \
54                -message "Note: CIF $filename contains no coordinates"
55        return
56    }
57    set expgui(choose) [lindex $coordblocks 0]
58    # there is more than one appropriate block
59    if {[llength $coordblocks] > 1} {
60        catch {destroy .choose}
61        toplevel .choose
62        wm title .choose "Choose CIF Block"
63        bind .choose <Key-F1> "MakeWWWHelp expguierr.html ChooseCIF"
64        grid [label .choose.0 -text \
65                "More than one block in CIF $filename\ncontains coordinates.\n\nSelect the block to use" \
66                ] -row 0 -column 0 -columnspan 2
67        set row 0
68        foreach i $coordblocks {
69            incr row
70            set name ""
71            catch {set name [set block${i}(data_)]}
72            grid [radiobutton .choose.$row -value $i \
73                    -text "block $i ($name)" -variable expgui(choose)] \
74                    -row $row -column 0 -sticky w
75        }
76        grid [button .choose.browse -text CIF\nBrowser -command \
77                "CallBrowseCIF $CIF(txt) [list $allblocks] [list $coordblocks] .choose.cif" \
78                ] -row 1 -rowspan $row -column 1 
79        grid [button .choose.ok -text OK -command "destroy .choose"] \
80                -row [incr row] -column 0 -sticky w
81        grid [button .choose.help -text Help -bg yellow \
82            -command "MakeWWWHelp expguierr.html ChooseCIF"] \
83            -column 1 -row $row -sticky e
84        putontop .choose
85        tkwait window .choose
86        # fix grab...
87        afterputontop
88    }
89
90    set i $expgui(choose)
91    # get the space group
92    set spg {}
93    set sgnum {}
94    set msg {}
95    catch {
96        set spg [ValueFromCIF block${i} _symmetry_space_group_name_h-m]
97        set sgtmp [string toupper $spg]
98        # remove spaces from space group
99        regsub -all " " $sgtmp "" sgtmp
100        # check for final H
101        if {[string range $sgtmp end end] == "H"} {
102            set sgtmp [string range $sgtmp 0 end-1]
103        }
104        # make a copy where we treat bar 3 as the same as 3
105        regsub -- "-3" $sgtmp "3" sgtmp3
106        # see if this space group exists in the table
107        set fp1 [open [file join \
108                $expgui(scriptdir) spacegrp.ref] r]
109        while {[gets $fp1 line] >= 0} {
110            set testsg [string toupper [lindex $line 8]]
111            regsub -all " " $testsg "" testsg
112            if {$testsg == $sgtmp} {
113                set spg [lindex $line 8]
114                set sgnum [lindex $line 1]
115                break
116            } elseif {[lindex $line 1] >= 200} {
117                regsub -- "-3" $testsg "3" testsg3
118                if {$testsg3 == $sgtmp3} {
119                    set spg [lindex $line 8]
120                    set sgnum [lindex $line 1]
121                    break
122                }
123            } elseif {[lindex $line 1] <= 18} {
124                # monoclinic: change operators of form "1 xxx 1" to "xxx"
125                regsub -- " 1 (.*) 1" [string toupper [lindex $line 8]] "\\1" testsg
126                # remove spaces from space group
127                regsub -all " " $testsg "" testsg
128                if {$testsg == $sgtmp} {
129                    set spg [lindex $line 8]
130                    set sgnum [lindex $line 1]
131                    break
132                }
133            }
134        }
135        close $fp1
136        if {$spg == ""} {
137            set msg "Warning: a Space Group must be specified"
138        } elseif {$sgnum == ""} {
139            set msg "Warning: the Space Group ($spg) is likely incorrect for GSAS"
140        }
141    }
142    set cell {}
143    foreach var {_cell_length_a _cell_length_b _cell_length_c \
144            _cell_angle_alpha _cell_angle_beta _cell_angle_gamma} {
145        # leave blank any unspecified data items
146        set val {}
147        catch {set val [ValueFromCIF block${i} $var]}
148        lappend cell [lindex [ParseSU $val] 0]
149    }
150   
151    set atomlist {}
152    set lbllist {}
153    catch {
154        set lbllist [ValueFromCIF block${i} _atom_site_label]
155    }
156    set uisolist {}
157    set Uconv 1
158    catch {
159        set uisolist [ValueFromCIF block${i} _atom_site_u_iso_or_equiv]
160    }
161    if {$uisolist == ""} {
162        catch {
163            set uisolist [ValueFromCIF block${i} _atom_site_b_iso_or_equiv]
164            set Uconv [expr 1/(8*3.14159*3.14159)]
165        }
166    }
167    set occlist {}
168    catch {
169        set occlist [ValueFromCIF block${i} _atom_site_occupancy]
170    }
171    set typelist {}
172    catch {
173        set typelist [ValueFromCIF block${i} _atom_site_type_symbol]
174    }
175    foreach x [ValueFromCIF block${i} _atom_site_fract_x] \
176            y [ValueFromCIF block${i} _atom_site_fract_y] \
177            z [ValueFromCIF block${i} _atom_site_fract_z] \
178            lbl $lbllist uiso $uisolist occ $occlist type $typelist {
179        # deal with defaults
180        if {$occ == "" || $occ == "."} {set occ 1.0}
181        if {$uiso == "" || $uiso == "."} {set uiso 0.025}
182        # should not be any quotes, but remove them, if there are
183        foreach var {lbl type} {
184            foreach char {' \"} {
185                set q {\\}
186                append q $char
187                set hidden [regsub -all $q [set $var] \200 $var]
188                if {[string index [set $var] 0] == $char} {
189                    regsub -all $char [set $var] {} $var
190                }
191                if {$hidden} {regsub -all \200 [set $var] $char $var}
192            }
193        }
194        # CIF specifies types as Cu2+; GSAS uses Cu+2
195        if {[regexp {([A-Za-z]+)([1-9])([+-])} $type junk elem sign val]} {
196            set type ${elem}${val}$sign
197        }
198        # if type is missing, attempt to parse an element in the label
199        if {$type == "" && $lbl != ""} {
200            regexp {[A-Za-z][A-Za-z]?} $lbl type
201        }
202        # get rid of standard uncertainies
203        foreach var {x y z occ uiso} {
204            catch {
205                set $var [lindex [ParseSU [set $var]] 0]
206            }
207        }
208        # convert Biso to Uiso (if needed)
209        if {$Uconv != 1} {
210            catch {set $uiso [expr $Uconv*$uiso]}
211        }
212        lappend atomlist [list $lbl $x $y $z $type $occ $uiso]
213    }
214
215    # clean up -- get rid of the CIF arrays & window
216    for {set i 1} {$i <= $blocks} {incr i} {
217        unset block$i
218    }
219    destroy $file
220    return "[list $spg] [list $cell] [list $atomlist] [list $msg]"
221}
222
223
224proc CallBrowseCIF {txt blocklist selected frame} {
225    # is there a defined list of dictionary files?
226    if {[catch {set ::CIF(dictfilelist)}]} {
227        set dictfilelist [glob -nocomplain \
228                              [file join $::expgui(gsasdir) data *.dic]]
229        foreach file $dictfilelist {
230            lappend ::CIF(dictfilelist) $file
231            set ::CIF(dict_$file) 1
232        }
233    }
234    # load the initial CIF dictionaries
235    LoadDictIndices
236   
237    BrowseCIF $txt $blocklist $selected $frame
238}
Note: See TracBrowser for help on using the repository browser.