|
1 | 1 | #!/usr/bin/env python |
2 | | -############################################################################## |
3 | | -# |
4 | | -# diffpy.structure by DANSE Diffraction group |
5 | | -# Simon J. L. Billinge |
6 | | -# (c) 2006 trustees of the Michigan State University. |
7 | | -# All rights reserved. |
8 | | -# |
9 | | -# File coded by: Pavol Juhas |
10 | | -# |
11 | | -# See AUTHORS.txt for a list of people who contributed. |
12 | | -# See LICENSE_DANSE.txt for license information. |
13 | | -# |
14 | | -############################################################################## |
15 | 2 |
|
16 | | -"""anyeye view structure file in atomeye |
17 | | -Usage: anyeye [options] strufile |
18 | | -
|
19 | | -anyeye understands more structure formats than atomeye. It converts strufile |
20 | | -to a temporary XCFG file which is opened in atomeye. Supported file formats: |
21 | | - inputFormats |
22 | | -
|
23 | | -Options: |
24 | | - -f, --formula override chemical formula in strufile, formula defines |
25 | | - elements in the same order as in strufile, e.g, Na4Cl4 |
26 | | - -w, --watch watch input file for changes |
27 | | - --viewer=VIEWER the structure viewer program, by default "atomeye". |
28 | | - The program will be executed as "VIEWER structurefile" |
29 | | - --formats=FORMATS comma separated list of file formats that are understood |
30 | | - by the VIEWER, by default "xcfg,pdb". Files of other |
31 | | - formats will be converted to the first listed format. |
32 | | - -h, --help display this message and exit |
33 | | - -V, --version show script version and exit |
34 | 3 | """ |
| 4 | +Temporary support for old import name. |
35 | 5 |
|
36 | | -from __future__ import print_function |
37 | | - |
38 | | -import sys |
39 | | -import os |
40 | | -import re |
41 | | -import signal |
42 | | -from diffpy.structure import StructureFormatError |
43 | | - |
44 | | -# parameter dictionary |
45 | | -pd = { 'formula' : None, |
46 | | - 'watch' : False, |
47 | | - 'viewer' : 'atomeye', |
48 | | - 'formats' : ['xcfg', 'pdb'], |
49 | | -} |
50 | | - |
51 | | - |
52 | | -def usage(style = None): |
53 | | - """show usage info, for style=="brief" show only first 2 lines""" |
54 | | - import os.path |
55 | | - myname = os.path.basename(sys.argv[0]) |
56 | | - msg = __doc__.replace("anyeye", myname) |
57 | | - if style == 'brief': |
58 | | - msg = msg.split("\n")[1] + "\n" + \ |
59 | | - "Try `%s --help' for more information." % myname |
60 | | - else: |
61 | | - from diffpy.structure.parsers import inputFormats |
62 | | - fmts = [ f for f in inputFormats() if f != 'auto' ] |
63 | | - msg = msg.replace("inputFormats", " ".join(fmts)) |
64 | | - print(msg) |
65 | | - return |
66 | | - |
67 | | - |
68 | | -def version(): |
69 | | - from diffpy.structure import __version__ |
70 | | - print("anyeye", __version__) |
71 | | - return |
72 | | - |
73 | | - |
74 | | -def loadStructureFile(filename, format="auto"): |
75 | | - """Load structure from specified file. |
76 | | -
|
77 | | - Return a tuple of (Structure, fileformat). |
78 | | - """ |
79 | | - from diffpy.structure import Structure |
80 | | - stru = Structure() |
81 | | - p = stru.read(filename, format) |
82 | | - fileformat = p.format |
83 | | - return (stru, fileformat) |
84 | | - |
85 | | - |
86 | | -def convertStructureFile(pd): |
87 | | - # make temporary directory on the first pass |
88 | | - if 'tmpdir' not in pd: |
89 | | - from tempfile import mkdtemp |
90 | | - pd['tmpdir'] = mkdtemp() |
91 | | - strufile = pd['strufile'] |
92 | | - tmpfile = os.path.join(pd['tmpdir'], os.path.basename(strufile)) |
93 | | - pd['tmpfile'] = tmpfile |
94 | | - # speed up file processing in the watch mode |
95 | | - fmt = pd.get('format', 'auto') |
96 | | - stru = None |
97 | | - if fmt == 'auto': |
98 | | - stru, fmt = loadStructureFile(strufile) |
99 | | - pd['fmt'] = fmt |
100 | | - # if fmt is recognized by the viewer, use as is |
101 | | - if fmt in pd['formats'] and pd['formula'] is None: |
102 | | - import shutil |
103 | | - shutil.copyfile(strufile, tmpfile+'.tmp') |
104 | | - os.rename(tmpfile+'.tmp', tmpfile) |
105 | | - return |
106 | | - # otherwise convert to the first recognized viewer format |
107 | | - if stru is None: |
108 | | - stru = loadStructureFile(strufile, fmt)[0] |
109 | | - if pd['formula']: |
110 | | - formula = pd['formula'] |
111 | | - if len(formula) != len(stru): |
112 | | - emsg = "Formula has %i atoms while structure %i" % ( |
113 | | - len(formula), len(stru) ) |
114 | | - raise RuntimeError(emsg) |
115 | | - for a, el in zip(stru, formula): |
116 | | - a.element = el |
117 | | - elif format == "rawxyz": |
118 | | - for a in stru: |
119 | | - if a.element == "": a.element = "C" |
120 | | - stru.write(tmpfile+'.tmp', pd['formats'][0]) |
121 | | - os.rename(tmpfile+'.tmp', tmpfile) |
122 | | - return |
123 | | - |
124 | | - |
125 | | -def watchStructureFile(pd): |
126 | | - from time import sleep |
127 | | - strufile = pd['strufile'] |
128 | | - tmpfile = pd['tmpfile'] |
129 | | - while pd['watch']: |
130 | | - if os.path.getmtime(tmpfile) < os.path.getmtime(strufile): |
131 | | - convertStructureFile(pd) |
132 | | - sleep(1) |
133 | | - return |
134 | | - |
135 | | - |
136 | | -def cleanUp(pd): |
137 | | - if 'tmpfile' in pd: |
138 | | - os.remove(pd['tmpfile']) |
139 | | - del pd['tmpfile'] |
140 | | - if 'tmpdir' in pd: |
141 | | - os.rmdir(pd['tmpdir']) |
142 | | - del pd['tmpdir'] |
143 | | - return |
144 | | - |
145 | | - |
146 | | -def parseFormula(formula): |
147 | | - """parse chemical formula and return a list of elements""" |
148 | | - # remove all blanks |
149 | | - formula = re.sub(r'\s', '', formula) |
150 | | - if not re.match('^[A-Z]', formula): |
151 | | - raise RuntimeError("InvalidFormula '%s'" % formula) |
152 | | - elcnt = re.split('([A-Z][a-z]?)', formula)[1:] |
153 | | - ellst = [] |
154 | | - try: |
155 | | - for i in range(0, len(elcnt), 2): |
156 | | - el = elcnt[i] |
157 | | - cnt = elcnt[i+1] |
158 | | - cnt = (cnt == "") and 1 or int(cnt) |
159 | | - ellst.extend(cnt*[el]) |
160 | | - except ValueError: |
161 | | - emsg = "Invalid formula, %r is not valid count" % elcnt[i+1] |
162 | | - raise RuntimeError(emsg) |
163 | | - return ellst |
164 | | - |
165 | | - |
166 | | -def die(exit_status=0, pd={}): |
167 | | - cleanUp(pd) |
168 | | - sys.exit(exit_status) |
169 | | - |
170 | | - |
171 | | -def signalHandler(signum, stackframe): |
172 | | - # revert to default handler |
173 | | - signal.signal(signum, signal.SIG_DFL) |
174 | | - if signum == signal.SIGCHLD: |
175 | | - pid, exit_status = os.wait() |
176 | | - exit_status = (exit_status >> 8) + (exit_status & 0x00ff) |
177 | | - die(exit_status, pd) |
178 | | - else: |
179 | | - die(1, pd) |
180 | | - return |
181 | | - |
| 6 | +This module is deprecated and will be removed in version 3.1. |
| 7 | +""" |
182 | 8 |
|
183 | | -def main(): |
184 | | - import getopt |
185 | | - # default parameters |
186 | | - pd['watch'] = False |
187 | | - try: |
188 | | - opts, args = getopt.getopt(sys.argv[1:], "f:whV", |
189 | | - ["formula=", "watch", "viewer=", "formats=", |
190 | | - "help", "version"]) |
191 | | - except getopt.GetoptError as errmsg: |
192 | | - print(errmsg, file=sys.stderr) |
193 | | - die(2) |
194 | | - # process options |
195 | | - for o, a in opts: |
196 | | - if o in ("-f", "--formula"): |
197 | | - try: |
198 | | - pd['formula'] = parseFormula(a) |
199 | | - except RuntimeError as msg: |
200 | | - print(msg, file=sys.stderr) |
201 | | - die(2) |
202 | | - elif o in ("-w", "--watch"): |
203 | | - pd['watch'] = True |
204 | | - elif o == "--viewer": |
205 | | - pd['viewer'] = a |
206 | | - elif o == "--formats": |
207 | | - pd['formats'] = [w.strip() for w in a.split(',')] |
208 | | - elif o in ("-h", "--help"): |
209 | | - usage() |
210 | | - die() |
211 | | - elif o in ("-V", "--version"): |
212 | | - version() |
213 | | - die() |
214 | | - if len(args) < 1: |
215 | | - usage('brief') |
216 | | - die() |
217 | | - elif len(args) > 1: |
218 | | - print("too many structure files", file=sys.stderr) |
219 | | - die(2) |
220 | | - pd['strufile'] = args[0] |
221 | | - # trap the following signals |
222 | | - signal.signal(signal.SIGHUP, signalHandler) |
223 | | - signal.signal(signal.SIGQUIT, signalHandler) |
224 | | - signal.signal(signal.SIGSEGV, signalHandler) |
225 | | - signal.signal(signal.SIGTERM, signalHandler) |
226 | | - signal.signal(signal.SIGINT, signalHandler) |
227 | | - env = os.environ.copy() |
228 | | - if os.path.basename(pd['viewer']).startswith('atomeye'): |
229 | | - env['XLIB_SKIP_ARGB_VISUALS'] = "1" |
230 | | - # try to run the thing: |
231 | | - try: |
232 | | - convertStructureFile(pd) |
233 | | - spawnargs = (pd['viewer'], pd['viewer'], pd['tmpfile'], env) |
234 | | - # load strufile in atomeye |
235 | | - if pd['watch']: |
236 | | - signal.signal(signal.SIGCLD, signalHandler) |
237 | | - os.spawnlpe(os.P_NOWAIT, *spawnargs) |
238 | | - watchStructureFile(pd) |
239 | | - else: |
240 | | - status = os.spawnlpe(os.P_WAIT, *spawnargs) |
241 | | - die(status, pd) |
242 | | - except IOError as e: |
243 | | - print("%s: %s" % (args[0], e.strerror), file=sys.stderr) |
244 | | - die(1, pd) |
245 | | - except StructureFormatError as e: |
246 | | - print("%s: %s" % (args[0], e), file=sys.stderr) |
247 | | - die(1, pd) |
248 | | - return |
| 9 | +# TODO remove this module in version 3.1. |
249 | 10 |
|
| 11 | +from diffpy.structure.apps.anyeye import main |
250 | 12 |
|
251 | 13 | if __name__ == "__main__": |
252 | 14 | main() |
0 commit comments