Coverage for /Users/Newville/Codes/xraylarch/larch/wxxas/exafs_panel.py: 12%

440 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-11-09 10:08 -0600

1#!/usr/bin/env python 

2""" 

3Linear Combination panel 

4""" 

5import os 

6import time 

7import copy 

8import wx 

9import numpy as np 

10 

11from functools import partial 

12 

13from larch.math import index_of 

14from larch.wxlib import (BitmapButton, FloatCtrl, FloatSpin, ToggleButton, 

15 get_icon, SimpleText, pack, Button, HLine, Choice, 

16 plotlabels, Check, CEN, RIGHT, LEFT) 

17 

18from larch.xafs.xafsutils import etok, ktoe, FT_WINDOWS 

19from larch.xafs.pre_edge import find_e0 

20 

21from .xas_dialogs import EnergyUnitsDialog 

22from .taskpanel import TaskPanel 

23from .config import ATHENA_CLAMPNAMES, PlotWindowChoices 

24 

25np.seterr(all='ignore') 

26 

27# plot options: 

28mu_bkg = '\u03bC(E) + \u03bc0(E)' 

29chie = '\u03c7(E)' 

30chik = '\u03c7(k)' 

31chikwin = '\u03c7(k) + Window(k)' 

32chirmag = '|\u03c7(R)|' 

33chirre = 'Re[\u03c7(R)]' 

34chirmr = '|\u03c7(R)| + Re[\u03c7(R)]' 

35wavelet = 'EXAFS wavelet' 

36chir_w = '\u03c7(R) + Window(R)' 

37chiq = 'Filtered \u03c7(k)' 

38chikq = '\u03c7(k) + Filtered \u03c7(k)' 

39noplot = '<no plot>' 

40 

41PlotOne_Choices = [mu_bkg, chie, chik, chikwin, chirmag, chirre, chirmr, wavelet, 

42 chir_w, chiq, chikq] 

43PlotAlt_Choices = [noplot] + PlotOne_Choices 

44PlotSel_Choices = [chie, chik, chirmag, chirre] 

45 

46 

47PlotCmds = {mu_bkg: "plot_bkg({group:s}", 

48 chie: "plot_chie({group:s}", 

49 chik: "plot_chik({group:s}, show_window=False, kweight={plot_kweight:.0f}", 

50 chikwin: "plot_chik({group:s}, show_window=True, kweight={plot_kweight:.0f}", 

51 chirmag: "plot_chir({group:s}, show_mag=True, show_real=False, rmax={plot_rmax:.1f}", 

52 chirre: "plot_chir({group:s}, show_mag=False, show_real=True, rmax={plot_rmax:.1f}", 

53 chirmr: "plot_chir({group:s}, show_mag=True, show_real=True, rmax={plot_rmax:.1f}", 

54 chir_w: "plot_chir({group:s}, show_mag=True, show_real=True, show_window=True, rmax={plot_rmax:.1f}", 

55 chiq: "plot_chiq({group:s}, show_chik=False", 

56 chikq: "plot_chiq({group:s}, show_chik=True", 

57 wavelet: "plot_wavelet({group:s}, rmax={plot_rmax:.1f}", 

58 noplot: None} 

59 

60 

61CLAMPLIST = ('0', '1', '2', '5', '10', '20', '50', '100', '200', '500', '1000', 

62 '2000', '5000', '10000') 

63 

64autobk_cmd = """autobk({group:s}, rbkg={rbkg: .3f}, ek0={ek0: .4f}, 

65 kmin={bkg_kmin: .3f}, kmax={bkg_kmax: .3f}, kweight={bkg_kweight: .1f}, 

66 clamp_lo={bkg_clamplo: .1f}, clamp_hi={bkg_clamphi: .1f})""" 

67 

68xftf_cmd = """xftf({group:s}, kmin={fft_kmin: .3f}, kmax={fft_kmax: .3f}, dk={fft_dk: .3f}, 

69 kweight={fft_kweight: .3f}, window='{fft_kwindow:s}', rmax_out={fft_rmaxout:.3f})""" 

70 

71xftr_cmd = """xftr({group:s}, rmin={fft_rmin: .3f}, rmax={fft_rmax: .3f}, 

72 dr={fft_dr: .3f}, window='{fft_rwindow:s}')""" 

73 

74 

75class EXAFSPanel(TaskPanel): 

76 """EXAFS Panel""" 

77 def __init__(self, parent, controller, **kws): 

78 TaskPanel.__init__(self, parent, controller, panel='exafs', **kws) 

79 

80 self.skip_process = False 

81 self.last_plot = 'one' 

82 self.last_process_bkg = {} 

83 self.last_process_fft = {} 

84 self.last_process_time = time.time() - 5000 

85 

86 def build_display(self): 

87 panel = self.panel 

88 wids = self.wids 

89 self.skip_process = True 

90 

91 wids['plotone_op'] = Choice(panel, choices=PlotOne_Choices, 

92 action=self.onPlotOne, size=(175, -1)) 

93 wids['plotalt_op'] = Choice(panel, choices=PlotAlt_Choices, 

94 action=self.onPlotOne, size=(175, -1)) 

95 wids['plotsel_op'] = Choice(panel, choices=PlotSel_Choices, 

96 action=self.onPlotSel, size=(175, -1)) 

97 

98 wids['plotone_op'].SetStringSelection(chik) 

99 wids['plotsel_op'].SetStringSelection(chik) 

100 wids['plotalt_op'].SetStringSelection(noplot) 

101 

102 plot_one = Button(panel, 'Plot This Group', size=(175, -1), 

103 action=self.onPlotOne) 

104 

105 plot_sel = Button(panel, 'Plot Selected Groups', size=(175, -1), 

106 action=self.onPlotSel) 

107 

108 ## saveconf = Button(panel, 'Save as Default Settings', size=(200, -1), 

109 # action=self.onSaveConfigBtn) 

110 

111 wids['plot_voffset'] = FloatSpin(panel, value=0, digits=2, increment=0.25, 

112 action=self.onProcess) 

113 wids['plot_kweight'] = FloatSpin(panel, value=2, digits=1, increment=1, 

114 action=self.onProcess, 

115 min_val=0, max_val=5) 

116 wids['plot_kweight_alt'] = FloatSpin(panel, value=2, digits=1, increment=1, 

117 action=self.onProcess, 

118 min_val=0, max_val=5) 

119 

120 wids['plot_rmax'] = FloatSpin(panel, value=8, digits=1, increment=0.5, 

121 action=self.onProcess, 

122 min_val=2, max_val=20) 

123 wids['plot_win'] = Choice(panel, size=(60, -1), choices=PlotWindowChoices, 

124 action=self.onProcess) 

125 wids['plot_win'].SetStringSelection('2') 

126 

127 opts = dict(digits=2, increment=0.1, min_val=0, action=self.onProcess) 

128 wids['ek0'] = FloatSpin(panel, **opts) 

129 

130 wids['push_e0'] = Button(panel, 'Use as Normalization E0', size=(200, -1), 

131 action=self.onPushE0) 

132 wids['push_e0'].SetToolTip('Use this value for E0 in the Normalization Tab') 

133 

134 

135 opts['max_val'] = 6 

136 opts['action'] = self.onRbkg 

137 wids['rbkg'] = FloatSpin(panel, value=1.0, **opts) 

138 

139 opts['action'] = self.onProcess 

140 opts['max_val'] = 125 

141 bkg_kmin = self.add_floatspin('bkg_kmin', value=0, with_pin=True, **opts) 

142 bkg_kmax = self.add_floatspin('bkg_kmax', value=20, with_pin=True, **opts) 

143 fft_kmin = self.add_floatspin('fft_kmin', value=0, with_pin=True, **opts) 

144 fft_kmax = self.add_floatspin('fft_kmax', value=20, with_pin=True, **opts) 

145 

146 wids['fft_dk'] = FloatSpin(panel, value=3, **opts) 

147 

148 opts.update({'increment': 0.1, 'digits': 2, 'max_val': 20}) 

149 fft_rmin = self.add_floatspin('fft_rmin', value=1, with_pin=True, **opts) 

150 fft_rmax = self.add_floatspin('fft_rmax', value=6, with_pin=True, **opts) 

151 

152 wids['fft_dr'] = FloatSpin(panel, value=0.5, **opts) 

153 wids['fft_rmaxout'] = FloatSpin(panel, value=12, min_val=2, 

154 increment=0.5, digits=1, max_val=20) 

155 

156 opts.update({'increment': 1, 'digits': 1, 'max_val': 5}) 

157 wids['bkg_kweight'] = FloatSpin(panel, value=2, **opts) 

158 wids['fft_kweight'] = FloatSpin(panel, value=2, **opts) 

159 

160 opts = dict(choices=CLAMPLIST, size=(80, -1), action=self.onProcess) 

161 wids['bkg_clamplo'] = Choice(panel, **opts) 

162 wids['bkg_clamphi'] = Choice(panel, **opts) 

163 

164 wids['fft_kwindow'] = Choice(panel, choices=list(FT_WINDOWS), 

165 action=self.onProcess, size=(125, -1)) 

166 

167 

168 wids['fft_rwindow'] = Choice(panel, choices=list(FT_WINDOWS), 

169 action=self.onProcess, size=(125, -1)) 

170 wids['fft_rwindow'].SetStringSelection('Hanning') 

171 

172 

173 self.wids['is_frozen'] = Check(panel, default=False, label='Freeze Group', 

174 action=self.onFreezeGroup) 

175 

176 def add_text(text, dcol=1, newrow=True): 

177 panel.Add(SimpleText(panel, text), dcol=dcol, newrow=newrow) 

178 

179 def CopyBtn(name): 

180 return Button(panel, 'Copy', size=(60, -1), 

181 action=partial(self.onCopyParam, name)) 

182 copy_all = Button(panel, 'Copy All Parameters', size=(175, -1), 

183 action=partial(self.onCopyParam, 'all')) 

184 

185 

186 panel.Add(SimpleText(panel, 'EXAFS Data Reduction and Fourier Transforms', 

187 size=(350, -1), **self.titleopts), style=LEFT, dcol=6) 

188 

189 panel.Add(plot_sel, newrow=True) 

190 panel.Add(self.wids['plotsel_op'], dcol=2) 

191 

192 add_text('Vertical offset: ', newrow=False) 

193 panel.Add(wids['plot_voffset'], dcol=2) 

194 

195 panel.Add(plot_one, newrow=True) 

196 panel.Add(self.wids['plotone_op'], dcol=2) 

197 

198 add_text('Plot k weight: ', newrow=False) 

199 panel.Add(wids['plot_kweight']) 

200 

201 add_text('Add Second Plot: ', newrow=True) 

202 panel.Add(self.wids['plotalt_op'], dcol=2) 

203 add_text('Plot2 k weight: ', newrow=False) 

204 panel.Add(wids['plot_kweight_alt']) 

205 add_text('Window for Second Plot: ', newrow=True) 

206 panel.Add(self.wids['plot_win'], dcol=2) 

207 add_text('Plot R max: ', newrow=False) 

208 panel.Add(wids['plot_rmax']) 

209 

210 panel.Add(HLine(panel, size=(500, 3)), dcol=6, newrow=True) 

211 

212 panel.Add(SimpleText(panel, ' Background subtraction', size=(200, -1), 

213 **self.titleopts), dcol=2, style=LEFT, newrow=True) 

214 panel.Add(SimpleText(panel, 'Copy To Selected Groups:'), 

215 style=RIGHT, dcol=3) 

216 

217 

218 add_text('E k=0: ') 

219 panel.Add(wids['ek0']) 

220 panel.Add(wids['push_e0'], dcol=2) 

221 panel.Add(CopyBtn('ek0'), style=RIGHT) 

222 

223 add_text('R bkg: ') 

224 panel.Add(wids['rbkg']) 

225 panel.Add((10, 10), dcol=2) 

226 panel.Add(CopyBtn('rbkg'), style=RIGHT) 

227 

228 add_text('k min: ') 

229 panel.Add(bkg_kmin) 

230 panel.Add(SimpleText(panel, 'k max:'), style=LEFT) 

231 panel.Add(bkg_kmax) 

232 panel.Add(CopyBtn('bkg_krange'), style=RIGHT) 

233 

234 add_text('kweight: ', newrow=True) 

235 panel.Add(wids['bkg_kweight']) 

236 panel.Add((10, 10), dcol=2) 

237 panel.Add(CopyBtn('bkg_kweight'), style=RIGHT) 

238 

239 add_text('Clamps Low E: ', newrow=True) 

240 panel.Add( wids['bkg_clamplo']) 

241 add_text('high E: ', newrow=False) 

242 panel.Add( wids['bkg_clamphi']) 

243 panel.Add(CopyBtn('bkg_clamp'), style=RIGHT) 

244 

245 panel.Add(HLine(panel, size=(500, 3)), dcol=6, newrow=True) 

246 

247 panel.Add(SimpleText(panel, ' Fourier transform (k->R) ', size=(275, -1), 

248 **self.titleopts), dcol=2, style=LEFT, newrow=True) 

249 panel.Add(SimpleText(panel, 'Copy To Selected Groups:'), 

250 style=RIGHT, dcol=3) 

251 

252 panel.Add(SimpleText(panel, 'k min: '), newrow=True) 

253 panel.Add(fft_kmin) 

254 panel.Add(SimpleText(panel, 'k max:'), style=LEFT) 

255 panel.Add(fft_kmax) 

256 panel.Add(CopyBtn('fft_krange'), style=RIGHT) 

257 

258 panel.Add(SimpleText(panel, 'k weight : '), newrow=True) 

259 panel.Add(wids['fft_kweight']) 

260 panel.Add((10, 10), dcol=2) 

261 panel.Add(CopyBtn('fft_kweight'), style=RIGHT) 

262 

263 panel.Add(SimpleText(panel, 'k window : '), newrow=True) 

264 panel.Add(wids['fft_kwindow']) 

265 panel.Add(SimpleText(panel, 'dk : ')) 

266 panel.Add(wids['fft_dk']) 

267 panel.Add(CopyBtn('fft_kwindow'), style=RIGHT) 

268 

269 panel.Add(SimpleText(panel, 'R max output: '), newrow=True) 

270 panel.Add(wids['fft_rmaxout']) 

271 panel.Add((10, 10), dcol=2) 

272 panel.Add(CopyBtn('fft_rmaxout'), style=RIGHT) 

273 

274 panel.Add(HLine(panel, size=(500, 3)), dcol=6, newrow=True) 

275 

276 panel.Add(SimpleText(panel, ' Back Fourier transform (R->q) ', size=(275, -1), 

277 **self.titleopts), dcol=2, style=LEFT, newrow=True) 

278 panel.Add(SimpleText(panel, 'Copy To Selected Groups:'), 

279 style=RIGHT, dcol=3) 

280 

281 panel.Add(SimpleText(panel, 'R min: '), newrow=True) 

282 panel.Add(fft_rmin) 

283 

284 panel.Add(SimpleText(panel, 'R max:'), style=LEFT) 

285 panel.Add(fft_rmax) 

286 panel.Add(CopyBtn('fft_rrange'), style=RIGHT) 

287 

288 panel.Add(SimpleText(panel, 'R window : '), newrow=True) 

289 panel.Add(wids['fft_rwindow']) 

290 panel.Add(SimpleText(panel, 'dR : ')) 

291 panel.Add(wids['fft_dr']) 

292 

293 panel.Add(CopyBtn('fft_rwindow'), style=RIGHT) 

294 panel.Add((10, 10), newrow=True) 

295 panel.Add(self.wids['is_frozen'], dcol=1, newrow=True) 

296 panel.Add(copy_all, dcol=5, style=RIGHT) 

297 

298 panel.pack() 

299 

300 sizer = wx.BoxSizer(wx.VERTICAL) 

301 sizer.Add((10, 10), 0, LEFT, 3) 

302 sizer.Add(panel, 1, LEFT, 3) 

303 pack(self, sizer) 

304 self.skip_process = False 

305 

306 def get_config(self, dgroup=None): 

307 """get and set processing configuration for a group""" 

308 if dgroup is None: 

309 dgroup = self.controller.get_group() 

310 if dgroup is None: 

311 return self.get_defaultconfig() 

312 

313 conf = getattr(dgroup.config, self.configname, None) 

314 if conf is None: 

315 conf = self.get_defaultconfig() 

316 

317 ek0 = getattr(dgroup, 'ek0', None) 

318 if ek0 is None: 

319 ek0 = conf.get('ek0', None) 

320 if ek0 is None: 

321 nconf = getattr(dgroup.config, 'xasnorm', {'e0': None}) 

322 ek0 = nconf.get('e0', None) 

323 if ek0 is None: 

324 ek0 = min(dgroup.energy) 

325 e0val = getattr(dgroup, 'e0', None) 

326 if e0val is not None: 

327 ek0 = e0val 

328 if getattr(dgroup, 'ek0', None) is None: 

329 dgroup.ek0 = ek0 

330 

331 kmax = etok(max(dgroup.energy) - ek0) 

332 

333 bkg_kmax = conf.get('bkg_kmax', -1) 

334 if bkg_kmax < 0 or bkg_kmax > kmax: 

335 conf['bkg_kmax'] = 0.25*int(kmax*4.0 + 1.0) 

336 

337 fft_kmax = conf.get('fft_kmax', -1) 

338 if fft_kmax < 0 or fft_kmax > kmax: 

339 conf['fft_kmax'] = 0.25*int(kmax*4.0 - 1.0) 

340 

341 fft_rmin = conf.get('fft_rmin', -1) 

342 if fft_rmin: 

343 conf['fft_rmin'] = conf['rbkg'] 

344 

345 setattr(dgroup.config, self.configname, conf) 

346 return conf 

347 

348 def fill_form(self, dgroup): 

349 """fill in form from a data group""" 

350 opts = self.get_config(dgroup) 

351 self.dgroup = dgroup 

352 if not (hasattr(dgroup, 'norm') and hasattr(dgroup, 'e0')): 

353 self.xasmain.process_normalization(dgroup) 

354 

355 self.skip_process = True 

356 wids = self.wids 

357 ek0 = getattr(dgroup, 'ek0', None) 

358 if ek0 is None: 

359 ek0 = dgroup.ek0 = getattr(dgroup, 'e0', None) 

360 if ek0 is None: 

361 ek0 = dgroup.ek0 = dgroup.e0 = find_e0(dgroup) 

362 if ek0 is None: 

363 print("cannot determine E0 for this group") 

364 return 

365 

366 rbkg = getattr(dgroup, 'rbkg', None) 

367 if rbkg is None: 

368 rkbg = dgroup.rbkg = opts.get('rbkg', 1.0) 

369 

370 for attr in ('ek0', 'rbkg'): 

371 wids[attr].SetValue(getattr(dgroup, attr)) 

372 

373 for attr in ('bkg_kmin', 'bkg_kmax', 'bkg_kweight', 'fft_kmin', 

374 'fft_kmax', 'fft_kweight', 'fft_dk', 'fft_rmaxout', 

375 'plot_rmax'): 

376 try: 

377 wids[attr].SetValue(float(opts.get(attr))) 

378 except: 

379 pass 

380 

381 for attr in ('bkg_clamplo', 'bkg_clamphi'): 

382 val = opts.get(attr, 0) 

383 try: 

384 val = float(val) 

385 except: 

386 if isinstance(val, str): 

387 val = ATHENA_CLAMPNAMES.get(val.lower(), 0) 

388 try: 

389 wids[attr].SetStringSelection("%d" % int(val)) 

390 except: 

391 print(f"could not set '{attr:s}' to {val}") 

392 

393 for attr in ('fft_kwindow', 'plotone_op', 'plotalt_op'): # 'plotsel_op', 

394 if attr in opts: 

395 wids[attr].SetStringSelection(opts[attr]) 

396 

397 frozen = opts.get('is_frozen', False) 

398 if hasattr(dgroup, 'is_frozen'): 

399 frozen = dgroup.is_frozen 

400 

401 self.wids['is_frozen'].SetValue(frozen) 

402 self._set_frozen(frozen) 

403 

404 self.skip_process = False 

405 

406 def read_form(self, dgroup=None, as_copy=False): 

407 "read form, return dict of values" 

408 skip_save = self.skip_process 

409 self.skip_process = True 

410 if dgroup is None: 

411 dgroup = self.controller.get_group() 

412 self.dgroup = dgroup 

413 

414 conf = self.get_config() 

415 if dgroup is not None: 

416 conf['group'] = dgroup.groupname 

417 

418 wids = self.wids 

419 for attr in ('ek0', 'rbkg', 'bkg_kmin', 'bkg_kmax', 

420 'bkg_kweight', 'fft_kmin', 'fft_kmax', 

421 'fft_kweight', 'fft_dk', 'fft_rmaxout', 

422 'fft_rmin', 'fft_rmax', 'fft_dr', 

423 'plot_kweight', 'plot_rmax', 

424 'plot_kweight_alt', 'plot_voffset'): 

425 conf[attr] = wids[attr].GetValue() 

426 

427 for attr in ('bkg_clamplo', 'bkg_clamphi', 'plot_win'): 

428 conf[attr] = int(wids[attr].GetStringSelection()) 

429 

430 for attr in ('fft_kwindow', 'fft_rwindow', 'plotone_op', 

431 'plotsel_op', 'plotalt_op'): 

432 conf[attr] = wids[attr].GetStringSelection() 

433 time.sleep(0.001) 

434 self.skip_process = skip_save 

435 if as_copy: 

436 conf = copy.deepcopy(conf) 

437 if dgroup is not None: 

438 setattr(dgroup.config, self.configname, conf) 

439 return conf 

440 

441 def onSaveConfigBtn(self, evt=None): 

442 self.set_defaultconfig(self.read_form()) 

443 

444 def onPushE0(self, evt=None): 

445 conf = self.read_form() 

446 dgroup = self.controller.get_group() 

447 if dgroup is not None: 

448 nconf = getattr(dgroup.config, 'xasnorm', {'e0': None}) 

449 nconf['auto_e0'] = False 

450 nconf['e0'] = dgroup.e0 = conf['ek0'] 

451 

452 def onCopyParam(self, name=None, evt=None): 

453 conf = self.read_form() 

454 opts = {} 

455 def copy_attrs(*args): 

456 return {a: conf[a] for a in args} 

457 name = str(name) 

458 set_ek0 = set_rbkg = False 

459 if name == 'all': 

460 opts = copy_attrs( 'ek0', 'rbkg', 'bkg_kweight', 'fft_kweight', 

461 'bkg_kmin', 'bkg_kmax', 'bkg_clamplo', 

462 'bkg_clamphi', 'fft_kmin', 'fft_kmax', 

463 'fft_kwindow', 'fft_dk', 'fft_rmin', 

464 'fft_rmax', 'fft_rmaxout', 'fft_rwindow', 

465 'fft_dr') 

466 set_ek0 = True 

467 set_rbkg = True 

468 

469 elif name in ('ek0', 'rbkg', 'bkg_kweight', 'fft_kweight'): 

470 opts = copy_attrs(name) 

471 if name == 'ek0': 

472 set_ek0 = True 

473 elif name == 'rbkg': 

474 set_rbkg = True 

475 elif name == 'bkg_krange': 

476 opts = copy_attrs('bkg_kmin', 'bkg_kmax') 

477 elif name == 'bkg_clamp': 

478 opts = copy_attrs('bkg_clamplo', 'bkg_clamphi') 

479 elif name == 'fft_krange': 

480 opts = copy_attrs('fft_kmin', 'fft_kmax') 

481 elif name == 'fft_kwindow': 

482 opts = copy_attrs('fft_kwindow', 'fft_dk') 

483 elif name == 'fft_rrange': 

484 opts = copy_attrs('fft_rmin', 'fft_rmax') 

485 elif name == 'fft_rmaxout': 

486 opts = copy_attrs('fft_rmaxout',) 

487 elif name == 'fft_rwindow': 

488 opts = copy_attrs('fft_rwindow', 'fft_dr') 

489 

490 for checked in self.controller.filelist.GetCheckedStrings(): 

491 groupname = self.controller.file_groups[str(checked)] 

492 grp = self.controller.get_group(groupname) 

493 if grp != self.controller.group and not grp.is_frozen: 

494 self.update_config(opts, dgroup=grp) 

495 if set_ek0: 

496 grp.ek0 = opts['ek0'] 

497 if set_rbkg: 

498 grp.rbkg = opts['rbkg'] 

499 self.process(dgroup=grp, read_form=False) 

500 

501 

502 def _set_frozen(self, frozen): 

503 try: 

504 dgroup = self.controller.get_group() 

505 dgroup.is_frozen = frozen 

506 except: 

507 pass 

508 

509 for attr in ('ek0', 'rbkg', 'bkg_kmin', 'bkg_kmax', 'bkg_kweight', 

510 'fft_kmin', 'fft_kmax', 'fft_kweight', 'fft_dk', 

511 'fft_rmin', 'fft_rmax', 'fft_dr', 

512 'bkg_clamplo', 'bkg_clamphi', 'fft_kwindow'): 

513 self.wids[attr].Enable(not frozen) 

514 

515 def onFreezeGroup(self, evt=None): 

516 self._set_frozen(evt.IsChecked()) 

517 

518 

519 def onRbkg(self, event=None): 

520 self.wids['fft_rmin'].SetValue(self.wids['rbkg'].GetValue()) 

521 self.onProcess(event=event) 

522 

523 def onProcess(self, event=None): 

524 """ handle process events""" 

525 if self.skip_process or ((time.time() - self.last_process_time) < 0.5): 

526 return 

527 self.last_process_time = time.time() 

528 self.skip_process = True 

529 self.process(dgroup=self.dgroup, read_form=True) 

530 self.skip_process = False 

531 plotter = self.onPlotSel if self.last_plot=='selected' else self.onPlotOne 

532 wx.CallAfter(plotter) 

533 

534 def process(self, dgroup=None, read_form=True, force=False, **kws): 

535 conf = {} 

536 if dgroup is not None: 

537 self.dgroup = dgroup 

538 conf = getattr(dgroup.config, self.configname, None) 

539 if conf is None: 

540 conf = self.get_config(dgroup=dgroup) 

541 

542 if read_form: 

543 conf.update(self.read_form()) 

544 

545 conf.update(kws) 

546 if dgroup is None or 'fft_kwindow' not in conf: 

547 return 

548 

549 conf['group'] = dgroup.groupname 

550 

551 try: 

552 txt = autobk_cmd.format(**conf) 

553 except: 

554 conf.update(self.read_form()) 

555 

556 bkgpars = [] 

557 for attr in ('ek0', 'rbkg', 'bkg_kmin', 'bkg_kmax', 

558 'bkg_kweight', 'bkg_clamplo', 'bkg_clamphi'): 

559 val = conf.get(attr, 0.0) 

560 if val is None: 

561 val = -1.0 

562 bkgpars.append("%.3f" % val) 

563 bkgpars = ':'.join(bkgpars) 

564 lastpars = self.last_process_bkg.get(self.dgroup.groupname, '') 

565 if force or (bkgpars != lastpars): 

566 self.larch_eval(autobk_cmd.format(**conf)) 

567 self.last_process_bkg[self.dgroup.groupname] = bkgpars 

568 self.last_process_fft[self.dgroup.groupname] = '' 

569 

570 fftpars = [conf['fft_kwindow'], conf['fft_rwindow']] 

571 for attr in ('fft_kmin', 'fft_kmax', 'fft_kweight', 'fft_dk', 

572 'fft_rmin', 'fft_rmax', 'fft_dr', 'fft_rmaxout'): 

573 fftpars.append("%.3f" % conf.get(attr, 0.0)) 

574 fftpars = ':'.join(fftpars) 

575 if fftpars != self.last_process_fft.get(self.dgroup.groupname, ''): 

576 self.larch_eval(xftf_cmd.format(**conf)) 

577 self.larch_eval(xftr_cmd.format(**conf)) 

578 self.last_process_fft[self.dgroup.groupname] = fftpars 

579 

580 setattr(dgroup.config, self.configname, conf) 

581 

582 def plot(self, dgroup=None): 

583 if self.skip_plotting: 

584 return 

585 self.onPlotOne(dgroup=dgroup) 

586 

587 def onPlotOne(self, evt=None, dgroup=None): 

588 if self.skip_plotting: 

589 return 

590 conf = self.read_form(as_copy=True) 

591 if dgroup is not None: 

592 self.dgroup = dgroup 

593 conf['group'] = dgroup.groupname 

594 self.process(dgroup=self.dgroup) 

595 conf['title'] = '"%s"' % self.dgroup.filename 

596 

597 cmd = PlotCmds[conf['plotone_op']] + ", win=1, title={title:s})" 

598 # 2nd plot 

599 cmd2 = PlotCmds[conf['plotalt_op']] 

600 if cmd2 is not None: 

601 cmd2 = cmd2.replace('plot_kweight', 'plot_kweight_alt') 

602 cmd2 = cmd2 + ", win={plot_win:d}, title={title:s})" 

603 cmd = "%s\n%s" % (cmd, cmd2) 

604 self.controller.get_display(win=2) 

605 

606 self.larch_eval(cmd.format(**conf)) 

607 self.last_plot = 'one' 

608 

609 self.controller.set_focus() 

610 

611 

612 def onPlotSel(self, evt=None): 

613 if self.skip_plotting: 

614 return 

615 group_ids = self.controller.filelist.GetCheckedStrings() 

616 if len(group_ids) < 1: 

617 return 

618 

619 conf = self.read_form(as_copy=True) 

620 bcmd = PlotCmds[conf['plotsel_op']] 

621 conf['new'] = 'True' 

622 offset = conf['plot_voffset'] 

623 for i, checked in enumerate(group_ids): 

624 groupname = self.controller.file_groups[str(checked)] 

625 dgroup = self.controller.get_group(groupname) 

626 if dgroup is not None: 

627 conf['group'] = dgroup.groupname 

628 conf['label'] = dgroup.filename 

629 conf['offset'] = offset * i 

630 if not hasattr(dgroup, 'chir_mag'): 

631 self.process(dgroup=dgroup, read_form=False) 

632 

633 extra = """, offset={offset:.3f}, win=1, delay_draw=True, 

634 label='{label:s}', new={new:s})""" 

635 cmd = "%s%s" % (bcmd, extra) 

636 self.larch_eval(cmd.format(**conf)) 

637 conf['new'] = 'False' 

638 

639 self.larch_eval("redraw(win=1, show_legend=True)") 

640 self.last_plot = 'selected' 

641 

642 self.controller.set_focus()