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

1""" 

2main Larch Applications 

3""" 

4import os 

5import sys 

6import locale 

7 

8import shutil 

9from argparse import ArgumentParser 

10 

11 

12import matplotlib 

13from pyshortcuts import make_shortcut, ico_ext, get_desktop 

14 

15from .site_config import icondir, uname, update_larch 

16from .version import __date__, make_banner, check_larchversion 

17 

18HAS_WXPYTHON = False 

19try: 

20 import wx 

21 HAS_WXPYTHON = True 

22except ImportError: 

23 pass 

24 

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 

29 

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 

39 

40def set_locale(): 

41 """set locale to 'C' for these applications, 

42 may need some improvement!!""" 

43 locale.setlocale(locale.LC_ALL, 'C') 

44 

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') ) 

54 

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) 

60 

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) 

74 

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} 

84 

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() 

94 

95def run_gse_dtcorrect(): 

96 """GSE DT Correct """ 

97 set_locale() 

98 use_mpl_wxagg() 

99 from .wxmap import DTViewer 

100 DTViewer().MainLoop() 

101 

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() 

109 

110run_xas_viewer = run_larix 

111 

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() 

120 

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() 

133 

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() 

140 

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() 

147 

148 

149def run_feff6l(): 

150 "run feff6l" 

151 from .xafs.feffrunner import feff6l_cli 

152 feff6l_cli() 

153 

154def run_feff8l(): 

155 "run feff8l" 

156 from .xafs.feffrunner import feff8l_cli 

157 feff8l_cli() 

158 

159def run_larch_server(): 

160 "run larch XMLRPC server" 

161 from .xmlrpc_server import larch_server_cli 

162 larch_server_cli() 

163 

164 

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') 

172 

173 parser.add_argument('-v', '--version', dest='version', action='store_true', 

174 default=False, help='show version') 

175 

176 parser.add_argument("-e", "--exec", dest="noshell", action="store_true", 

177 default=False, help="execute script only, default = False") 

178 

179 parser.add_argument("-q", "--quiet", dest="quiet", action="store_true", 

180 default=False, help="set quiet mode, default = False") 

181 

182 parser.add_argument("-x", "--nowx", dest="nowx", action="store_true", 

183 default=False, help="set no wx graphics mode, default = False") 

184 

185 parser.add_argument("-w", "--wxgui", dest="wxgui", default=False, 

186 action='store_true', help="run Larch GUI") 

187 

188 parser.add_argument("-m", "--makeicons", dest="makeicons", action="store_true", 

189 default=False, help="create desktop icons") 

190 

191 parser.add_argument('-u', '--update', dest='update', action='store_true', 

192 default=False, help='update larch to the latest version') 

193 

194 parser.add_argument("-r", "--remote", dest="server_mode", action="store_true", 

195 default=False, help="run in remote server mode") 

196 

197 parser.add_argument("-p", "--port", dest="port", default='4966', 

198 help="port number for remote server") 

199 

200 parser.add_argument('scripts', nargs='*', 

201 help='larch or python scripts to run on startup') 

202 

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 

210 

211 with_wx = HAS_WXPYTHON and (not args.nowx) 

212 

213 # create desktop icons 

214 if args.makeicons: 

215 make_desktop_shortcuts() 

216 return 

217 

218 # run updates 

219 if args.update: 

220 update_larch() 

221 return 

222 

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() 

233 

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() 

240 

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) 

249 

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