Coverage for /Users/Newville/Codes/xraylarch/larch/apps.py: 20%
167 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-09 10:08 -0600
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-09 10:08 -0600
1"""
2main Larch Applications
3"""
4import os
5import sys
6import locale
8import shutil
9from argparse import ArgumentParser
12import matplotlib
13from pyshortcuts import make_shortcut, ico_ext, get_desktop
15from .site_config import icondir, uname, update_larch
16from .version import __date__, make_banner, check_larchversion
18HAS_WXPYTHON = False
19try:
20 import wx
21 HAS_WXPYTHON = True
22except ImportError:
23 pass
25if HAS_WXPYTHON:
26 # note: this will be needed for some macOS builds until wxPython 4.2.1 is released.
27 if uname == 'darwin':
28 wx.PyApp.IsDisplayAvailable = lambda _: True
30def use_mpl_wxagg():
31 """import matplotlib, set backend to wxAgg"""
32 if HAS_WXPYTHON:
33 try:
34 matplotlib.use('WXAgg', force=True)
35 return True
36 except ImportError:
37 pass
38 return False
40def set_locale():
41 """set locale to 'C' for these applications,
42 may need some improvement!!"""
43 locale.setlocale(locale.LC_ALL, 'C')
45# App Name, icon, terminal, Script / pyshortcuts command
46MainApps = (('Larch CLI', 'larch', True, 'larch'),
47 ('Larch Updater', 'larch', True, '_ -m pip install --upgrade xraylarch'),
48 ('Larch GUI', 'larch', False, 'larch --wxgui'),
49 ('XAS Viewer', 'onecone', False, 'xas_viewer'),
50 ('Larix', 'onecone', False, 'larix'),
51 ('GSE MapViewer', 'gse_xrfmap', False, 'gse_mapviewer'),
52 ('XRF Viewer', 'ptable', False, 'larch_xrf'),
53 ('XRD1D Viewer', 'larch', False, 'larch_xrd1d') )
55def make_desktop_shortcuts():
56 """make (or remake) desktop shortcuts for Larch apps"""
57 larchdir = os.path.join(get_desktop(), 'Larch')
58 if os.path.exists(larchdir):
59 shutil.rmtree(larchdir)
61 bindir = 'Scripts' if uname == 'win' else 'bin'
62 bindir = os.path.join(sys.prefix, bindir)
63 for appname, icon, term, script in MainApps:
64 kwargs = {'folder': 'Larch', 'terminal': term, 'name': appname}
65 if not script.startswith('_'):
66 script = os.path.normpath(os.path.join(bindir, script))
67 icon = os.path.join(icondir, icon)
68 if isinstance(ico_ext, (list, tuple)):
69 for ext in ico_ext:
70 ticon = f"{icon:s}.{ext:s}"
71 if os.path.exists(ticon):
72 icon = ticon
73 make_shortcut(script, icon=icon, **kwargs)
75def make_cli(description='run larch program', filedesc='data file'):
76 "make commandline apps"
77 parser = ArgumentParser(description=description)
78 parser.add_argument('filename', nargs='?', help=filedesc)
79 args = parser.parse_args()
80 filename = None
81 if 'filename' in args and args.filename is not None:
82 filename = os.path.abspath(args.filename)
83 return {'filename': filename}
85# entry points:
86def run_gse_mapviewer():
87 """Mapviewer"""
88 set_locale()
89 use_mpl_wxagg()
90 kwargs = make_cli(description="Larch's XRM Map Viewer and Analysis Program",
91 filedesc='XRM Map File (.h5)')
92 from .wxmap import MapViewer
93 MapViewer(check_version=True, **kwargs).MainLoop()
95def run_gse_dtcorrect():
96 """GSE DT Correct """
97 set_locale()
98 use_mpl_wxagg()
99 from .wxmap import DTViewer
100 DTViewer().MainLoop()
102def run_larix():
103 """Larix (was XAS Viewer)"""
104 set_locale()
105 use_mpl_wxagg()
106 from .wxxas import XASViewer, LARIX_TITLE
107 kwargs = make_cli(description=LARIX_TITLE)
108 XASViewer(check_version=True, **kwargs).MainLoop()
110run_xas_viewer = run_larix
112def run_larch_xrf():
113 """ XRF Display"""
114 set_locale()
115 use_mpl_wxagg()
116 kwargs = make_cli(description="Larch's XRF Viewer and Analysis Program",
117 filedesc='MCA File (.mca)')
118 from .wxlib.xrfdisplay import XRFApp
119 XRFApp(**kwargs).MainLoop()
121def run_epics_xrf():
122 """XRF Display for Epics Detectors"""
123 set_locale()
124 use_mpl_wxagg()
125 IMPORT_OK = False
126 try:
127 from .epics import EpicsXRFApp
128 IMPORT_OK = True
129 except ImportError:
130 print("cannot import EpicsXRFApp: try `pip install xraylarch[epics]`")
131 if IMPORT_OK:
132 EpicsXRFApp().MainLoop()
134def run_larch_xrd1d():
135 """XRD Display for 1D patternss"""
136 set_locale()
137 use_mpl_wxagg()
138 from .wxxrd import XRD1DApp
139 XRD1DApp().MainLoop()
141def run_xrd2d_viewer():
142 """XRD Display for 2D patternss"""
143 set_locale()
144 use_mpl_wxagg()
145 from .wxxrd import XRD2DViewer
146 XRD2DViewer().MainLoop()
149def run_feff6l():
150 "run feff6l"
151 from .xafs.feffrunner import feff6l_cli
152 feff6l_cli()
154def run_feff8l():
155 "run feff8l"
156 from .xafs.feffrunner import feff8l_cli
157 feff8l_cli()
159def run_larch_server():
160 "run larch XMLRPC server"
161 from .xmlrpc_server import larch_server_cli
162 larch_server_cli()
165## main larch cli or wxgui
166def run_larch():
167 """
168 main larch application launcher, running either
169 commandline repl program or wxgui
170 """
171 parser = ArgumentParser(description='run main larch program')
173 parser.add_argument('-v', '--version', dest='version', action='store_true',
174 default=False, help='show version')
176 parser.add_argument("-e", "--exec", dest="noshell", action="store_true",
177 default=False, help="execute script only, default = False")
179 parser.add_argument("-q", "--quiet", dest="quiet", action="store_true",
180 default=False, help="set quiet mode, default = False")
182 parser.add_argument("-x", "--nowx", dest="nowx", action="store_true",
183 default=False, help="set no wx graphics mode, default = False")
185 parser.add_argument("-w", "--wxgui", dest="wxgui", default=False,
186 action='store_true', help="run Larch GUI")
188 parser.add_argument("-m", "--makeicons", dest="makeicons", action="store_true",
189 default=False, help="create desktop icons")
191 parser.add_argument('-u', '--update', dest='update', action='store_true',
192 default=False, help='update larch to the latest version')
194 parser.add_argument("-r", "--remote", dest="server_mode", action="store_true",
195 default=False, help="run in remote server mode")
197 parser.add_argument("-p", "--port", dest="port", default='4966',
198 help="port number for remote server")
200 parser.add_argument('scripts', nargs='*',
201 help='larch or python scripts to run on startup')
203 args = parser.parse_args()
204 if args.version:
205 print(make_banner(with_libraries=True))
206 vinfo = check_larchversion()
207 if vinfo.update_available:
208 print(vinfo.message)
209 return
211 with_wx = HAS_WXPYTHON and (not args.nowx)
213 # create desktop icons
214 if args.makeicons:
215 make_desktop_shortcuts()
216 return
218 # run updates
219 if args.update:
220 update_larch()
221 return
223 # run in server mode
224 if args.server_mode:
225 if with_wx:
226 use_mpl_wxagg()
227 vinfo = check_larchversion()
228 if vinfo.update_available:
229 print(vinfo.message)
230 from .xmlrpc_server import LarchServer
231 server = LarchServer(host='localhost', port=int(args.port))
232 server.run()
234 # run wx Larch GUI
235 elif args.wxgui:
236 set_locale()
237 use_mpl_wxagg()
238 from .wxlib.larchframe import LarchApp
239 LarchApp(with_inspection=True).MainLoop()
241 # run wx Larch CLI
242 else:
243 if with_wx:
244 set_locale()
245 use_mpl_wxagg()
246 vinfo = check_larchversion()
247 if vinfo.update_available:
248 print(vinfo.message)
250 from .shell import Shell
251 cli = Shell(quiet=args.quiet, with_wx=with_wx)
252 # execute scripts listed on command-line
253 if args.scripts is not None:
254 for script in args.scripts:
255 if script.endswith('.py'):
256 cmd = f"import {script[:-3]}"
257 else:
258 cmd = f"run('{script}')"
259 cli.default(cmd)
260 # if interactive, start command loop
261 if not args.noshell:
262 try:
263 cli.cmdloop()
264 except ValueError:
265 pass