Coverage for /Users/Newville/Codes/xraylarch/larch/wxxas/xasnorm_panel.py: 7%
860 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#!/usr/bin/env python
2"""
3XANES Normalization panel
4"""
5import os
6import time
7import wx
8import numpy as np
10from functools import partial
12from xraydb import guess_edge, atomic_number
14from larch.utils import gformat
15from larch.math import index_of
16from larch.xafs.xafsutils import guess_energy_units
17from larch.xafs.pre_edge import find_e0
19from larch.wxlib import (BitmapButton, FloatCtrl, FloatSpin, get_icon,
20 SimpleText, pack, Button, HLine, Choice, Check,
21 GridPanel, CEN, RIGHT, LEFT, plotlabels,
22 get_zoomlimits, set_zoomlimits)
24from larch.utils.strutils import fix_varname, fix_filename, file2groupname
26from larch.utils.physical_constants import ATOM_NAMES
27from larch.wxlib.plotter import last_cursor_pos
28from .xas_dialogs import EnergyUnitsDialog
29from .taskpanel import TaskPanel, autoset_fs_increment
30from .config import make_array_choice, EDGES, ATSYMS, NNORM_CHOICES, NORM_METHODS
32np.seterr(all='ignore')
34PLOTOPTS_1 = dict(style='solid', marker='None')
35PLOTOPTS_2 = dict(style='short dashed', zorder=3, marker='None')
36PLOTOPTS_D = dict(style='solid', zorder=2, side='right', marker='None')
38PlotOne_Choices = make_array_choice(['mu','norm', 'flat', 'prelines',
39 'norm+flat', 'mback_norm', 'mback_poly',
40 'i0', 'norm+i0', 'dmude', 'norm+dmude',
41 'd2mude', 'norm+d2mude'])
44PlotSel_Choices = make_array_choice(['mu', 'norm', 'flat', 'dmude', 'd2mude'])
46Plot_EnergyRanges = {'full E range': None,
47 'E0 -20:+80eV': (-20, 80),
48 'E0 -30:+120eV': (-30, 120),
49 'E0 -50:+250eV': (-50, 250),
50 'E0 -100:+500eV': (-100, 500)}
53PlotOne_Choices_nonxas = {'Raw Data': 'mu',
54 'Scaled Data': 'norm',
55 'Derivative': 'dmude',
56 'Data + Derivative': 'norm+dmude'}
58PlotSel_Choices_nonxas = {'Raw Data': 'mu',
59 'Scaled Data': 'norm',
60 'Derivative': 'dmude'}
62FSIZE = 120
63FSIZEBIG = 175
65class XASNormPanel(TaskPanel):
66 """XAS normalization Panel"""
67 def __init__(self, parent, controller=None, **kws):
68 TaskPanel.__init__(self, parent, controller, panel='xasnorm', **kws)
70 def build_display(self):
71 panel = self.panel
72 self.wids = {}
73 self.last_plot_type = 'one'
75 trow = wx.Panel(panel)
76 plot_sel = Button(trow, 'Plot Selected Groups', size=(175, -1),
77 action=self.onPlotSel)
78 plot_one = Button(trow, 'Plot Current Group', size=(175, -1),
79 action=self.onPlotOne)
81 self.plotsel_op = Choice(trow, choices=list(PlotSel_Choices.keys()),
82 action=self.onPlotSel, size=(300, -1))
83 self.plotone_op = Choice(trow, choices=list(PlotOne_Choices.keys()),
84 action=self.onPlotOne, size=(300, -1))
86 self.plot_erange = Choice(trow, choices=list(Plot_EnergyRanges.keys()),
87 action=self.onPlotEither, size=(175, -1))
89 opts = {'digits': 2, 'increment': 0.05, 'value': 0, 'size': (FSIZE, -1)}
90 plot_voff = self.add_floatspin('plot_voff', with_pin=False,
91 parent=trow,
92 action=self.onVoffset,
93 max_val=10000, min_val=-10000,
94 **opts)
96 vysize, vxsize = plot_sel.GetBestSize()
97 voff_lab = wx.StaticText(parent=trow, label=' Y Offset:', size=(80, vxsize),
98 style=wx.RIGHT|wx.ALIGN_CENTRE_HORIZONTAL|wx.ST_NO_AUTORESIZE)
100 self.plot_erange.SetSelection(0)
101 self.plotone_op.SetSelection(1)
102 self.plotsel_op.SetSelection(1)
104 tsizer = wx.GridBagSizer(3, 3)
105 tsizer.Add(plot_sel, (0, 0), (1, 1), LEFT, 2)
106 tsizer.Add(self.plotsel_op, (0, 1), (1, 1), LEFT, 2)
107 tsizer.Add(voff_lab, (0, 2), (1, 1), RIGHT, 2)
108 tsizer.Add(plot_voff, (0, 3), (1, 1), RIGHT, 2)
109 tsizer.Add(plot_one, (1, 0), (1, 1), LEFT, 2)
110 tsizer.Add(self.plotone_op, (1, 1), (1, 1), LEFT, 2)
111 tsizer.Add(self.plot_erange, (1, 2), (1, 2), RIGHT, 2)
113 pack(trow, tsizer)
115 # atom row
116 atpanel = wx.Panel(panel)
117 self.wids['atsym'] = Choice(atpanel, choices=ATSYMS, size=(100, -1))
118 self.wids['edge'] = Choice(atpanel, choices=EDGES, size=(100, -1))
119 sat = wx.BoxSizer(wx.HORIZONTAL)
120 sat.Add(self.wids['atsym'], 0, LEFT, 4)
121 sat.Add(self.wids['edge'], 0, LEFT, 4)
122 pack(atpanel, sat)
124 # e0 row
125 e0_panel = wx.Panel(panel)
126 xas_e0 = self.add_floatspin('e0', action=self.onSet_XASE0Val,
127 min_val=-1000, max_val=1e7, digits=3,
128 increment=0.05, value=0, size=(FSIZEBIG, -1),
129 parent=e0_panel)
131 self.wids['auto_e0'] = Check(e0_panel, default=True, label='auto?',
132 action=self.onAuto_XASE0)
133 self.wids['show_e0'] = Check(e0_panel, default=True, label='show?',
134 action=self.onSet_XASE0)
136 sx = wx.BoxSizer(wx.HORIZONTAL)
137 sx.Add(xas_e0, 0, LEFT, 4)
138 sx.Add(self.wids['auto_e0'], 0, LEFT, 4)
139 sx.Add(self.wids['show_e0'], 0, LEFT, 4)
140 pack(e0_panel, sx)
142 # step row
143 step_panel = wx.Panel(panel)
144 xas_step = self.add_floatspin('step', action=self.onSet_XASStep, with_pin=False,
145 min_val=-1000.0, max_val=1e7, digits=4, increment=0.05,
146 value=0.1, size=(FSIZEBIG, -1), parent=step_panel)
147 self.wids['auto_step'] = Check(step_panel, default=True, label='auto?',
148 action=self.onNormMethod)
149 sx = wx.BoxSizer(wx.HORIZONTAL)
150 sx.Add(xas_step, 0, LEFT, 4)
151 sx.Add(self.wids['auto_step'], 0, LEFT, 4)
152 pack(step_panel, sx)
155 self.wids['energy_ref'] = Choice(panel, choices=['None'],
156 action=self.onEnergyRef, size=(300, -1))
158 self.wids['nvict'] = Choice(panel, choices=('0', '1', '2', '3'),
159 size=(100, -1), action=self.onNormMethod,
160 default=0)
162 self.wids['nnorm'] = Choice(panel, choices=list(NNORM_CHOICES.keys()),
163 size=(150, -1), action=self.onNormMethod,
164 default=0)
166 opts = {'size': (FSIZE, -1), 'digits': 2, 'increment': 5.0, 'action': self.onSet_Ranges,
167 'min_val':-99000, 'max_val':99000}
168 defaults = self.get_defaultconfig()
170 pre_panel = wx.Panel(panel)
171 xas_pre1 = self.add_floatspin('pre1', value=defaults['pre1'], parent=pre_panel, **opts)
172 xas_pre2 = self.add_floatspin('pre2', value=defaults['pre2'], parent=pre_panel, **opts)
173 self.wids['show_pre'] = Check(pre_panel, default=False, label='show?',
174 action=self.onSet_XASE0)
176 sx = wx.BoxSizer(wx.HORIZONTAL)
177 sx.Add(xas_pre1, 0, LEFT, 4)
178 sx.Add(SimpleText(pre_panel, ' : '), 0, LEFT, 4)
179 sx.Add(xas_pre2, 0, LEFT, 4)
180 sx.Add(self.wids['show_pre'], 0, LEFT, 4)
181 pack(pre_panel, sx)
183 nor_panel = wx.Panel(panel)
184 xas_norm1 = self.add_floatspin('norm1', value=defaults['norm1'], parent=nor_panel, **opts)
185 xas_norm2 = self.add_floatspin('norm2', value=defaults['norm2'], parent=nor_panel, **opts)
187 self.wids['show_norm'] = Check(nor_panel, default=False, label='show?',
188 action=self.onSet_XASE0)
189 sx = wx.BoxSizer(wx.HORIZONTAL)
190 sx.Add(xas_norm1, 0, LEFT, 4)
191 sx.Add(SimpleText(nor_panel, ' : '), 0, LEFT, 4)
192 sx.Add(xas_norm2, 0, LEFT, 4)
193 sx.Add(self.wids['show_norm'], 0, LEFT, 4)
194 pack(nor_panel, sx)
197 opts = {'digits': 3, 'increment': 0.05, 'value': 0, 'size': (FSIZEBIG, -1)}
199 opts.update({'value': 1.0, 'digits': 3})
200 scale = self.add_floatspin('scale', action=self.onSet_Scale, **opts)
202 self.wids['norm_method'] = Choice(panel, choices=NORM_METHODS,
203 size=(150, -1), action=self.onNormMethod)
204 self.wids['norm_method'].SetSelection(0)
205 self.wids['energy_shift'] = FloatSpin(panel, value=0, digits=3, increment=0.05,
206 min_val=-99000, max_val=99000,
207 action=self.onSet_EnergyShift,
208 size=(FSIZEBIG, -1))
211 self.wids['is_frozen'] = Check(panel, default=False, label='Freeze Group',
212 action=self.onFreezeGroup)
214 use_auto = Button(panel, 'Use Default Settings', size=(200, -1),
215 action=self.onAutoNorm)
216 copy_auto = Button(panel, 'Copy', size=(60, -1),
217 action=self.onCopyAuto)
219 def CopyBtn(name):
220 return Button(panel, 'Copy', size=(60, -1),
221 action=partial(self.onCopyParam, name))
223 copy_all = Button(panel, 'Copy All Parameters', size=(200, -1),
224 action=partial(self.onCopyParam, 'all'))
226 add_text = self.add_text
227 HLINEWID = 700
228 panel.Add(SimpleText(panel, 'XAS Pre-edge subtraction and Normalization',
229 size=(650, -1), **self.titleopts), style=LEFT, dcol=4)
230 panel.Add(trow, dcol=4, newrow=True)
232 panel.Add(HLine(panel, size=(HLINEWID, 3)), dcol=4, newrow=True)
233 add_text('Non-XAS Data Scale:')
234 panel.Add(scale)
235 panel.Add(SimpleText(panel, 'Copy to Selected Groups:'), style=RIGHT, dcol=2)
237 panel.Add(HLine(panel, size=(HLINEWID, 3)), dcol=4, newrow=True)
238 add_text('XAS Data:')
239 panel.Add(use_auto, dcol=2)
240 panel.Add(copy_auto, dcol=1, style=RIGHT)
242 add_text('Element and Edge: ', newrow=True)
243 panel.Add(atpanel, dcol=2)
245 add_text('Energy Reference : ')
246 panel.Add(self.wids['energy_ref'], dcol=2)
247 panel.Add(CopyBtn('energy_ref'), dcol=1, style=RIGHT)
249 add_text('Energy Shift : ')
250 panel.Add(self.wids['energy_shift'], dcol=2)
251 panel.Add(CopyBtn('energy_shift'), dcol=1, style=RIGHT)
253 add_text('E0 : ')
254 panel.Add(e0_panel, dcol=2)
255 panel.Add(CopyBtn('xas_e0'), dcol=1, style=RIGHT)
257 add_text('Edge Step: ')
258 panel.Add(step_panel, dcol=2)
259 panel.Add(CopyBtn('xas_step'), dcol=1, style=RIGHT)
261 panel.Add((5, 5), newrow=True)
262 panel.Add(HLine(panel, size=(HLINEWID, 3)), dcol=4, newrow=True)
264 add_text('Pre-edge range: ')
265 panel.Add(pre_panel, dcol=2)
266 panel.Add(CopyBtn('xas_pre'), dcol=1, style=RIGHT)
268 panel.Add(SimpleText(panel, 'Victoreen order:'), newrow=True)
269 panel.Add(self.wids['nvict'], dcol=2)
271 panel.Add((5, 5), newrow=True)
272 panel.Add(HLine(panel, size=(HLINEWID, 3)), dcol=4, newrow=True)
274 add_text('Normalization : ')
275 panel.Add(self.wids['norm_method'], dcol=2)
276 panel.Add(CopyBtn('xas_norm'), dcol=1, style=RIGHT)
278 add_text('Norm Energy range: ')
279 panel.Add(nor_panel, dcol=2)
280 panel.Add(SimpleText(panel, 'Polynomial Type:'), newrow=True)
281 panel.Add(self.wids['nnorm'], dcol=3)
283 panel.Add(HLine(panel, size=(HLINEWID, 3)), dcol=4, newrow=True)
284 panel.Add(self.wids['is_frozen'], newrow=True)
285 panel.Add(copy_all, dcol=3, style=RIGHT)
287 panel.pack()
289 sizer = wx.BoxSizer(wx.VERTICAL)
290 sizer.Add((5, 5), 0, LEFT, 3)
291 sizer.Add(panel, 0, LEFT, 3)
292 sizer.Add((5, 5), 0, LEFT, 3)
293 pack(self, sizer)
295 def get_config(self, dgroup=None):
296 """custom get_config to possibly inherit from Athena settings"""
297 if dgroup is None:
298 dgroup = self.controller.get_group()
299 if dgroup is None:
300 return self.get_defaultconfig()
301 self.read_form()
303 defconf = self.get_defaultconfig()
304 conf = getattr(dgroup.config, self.configname, None)
305 if conf is None:
306 conf = defconf
308 for k, v in defconf.items():
309 if k not in conf:
310 conf[k] = v
311 if conf.get('edge_step', None) is None:
312 conf['edge_step'] = getattr(dgroup, 'edge_step', 1)
314 atsym = '?'
315 if hasattr(dgroup, 'element'):
316 elem = getattr(dgroup, 'element', '?')
317 try:
318 z = int(elem)
319 atsym = ATSYMS[z]
320 except:
321 pass
322 if elem in ATSYMS[1:]:
323 atsym = elem
324 else:
325 try:
326 if elem.lower() in ATOM_NAMES:
327 z = 1 + ATOM_NAMES.index(eleme.lower())
328 atsym = ATSYMS[z]
329 except:
330 pass
332 conf['atsym'] = atsym
333 if atsym == '?':
334 conf['atsym'] = getattr(dgroup, 'atsym', atsym)
336 conf['edge'] = getattr(dgroup,'edge', conf['edge'])
338 xeref = getattr(dgroup, 'energy_ref', '')
339 fname = getattr(dgroup, 'filename', None)
340 if fname is None:
341 fname = getattr(dgroup, 'groupname', None)
342 if fname is None:
343 fname =file2groupname('unknown_group',
344 symtable=self._larch.symtable)
346 conf['energy_ref'] = getattr(dgroup, 'energy_ref', fname)
348 if conf['energy_ref'] in (None, 'None'):
349 conf['energy_ref'] = fname
352 conf['energy_shift'] = getattr(dgroup,'energy_shift', conf['energy_shift'])
354 if hasattr(dgroup, 'e0') and conf['atsym'] == '?':
355 atsym, edge = guess_edge(dgroup.e0)
356 conf['atsym'] = atsym
357 conf['edge'] = edge
359 if hasattr(dgroup, 'mback_params'):
360 conf['atsym'] = getattr(dgroup.mback_params, 'atsym', conf['atsym'])
361 conf['edge'] = getattr(dgroup.mback_params, 'edge', conf['edge'])
363 setattr(dgroup.config, self.configname, conf)
364 return conf
366 def fill_form(self, dgroup):
367 """fill in form from a data group"""
368 opts = self.get_config(dgroup)
369 self.skip_process = True
370 if self.is_xasgroup(dgroup):
371 if self.plotone_op.GetCount() != len(PlotOne_Choices.keys()):
372 self.plotone_op.SetChoices(list(PlotOne_Choices.keys()))
373 self.plotone_op.SetSelection(1)
374 if self.plotsel_op.GetCount() != len(PlotSel_Choices.keys()):
375 self.plotsel_op.SetChoices(list(PlotSel_Choices.keys()))
376 self.plotsel_op.SetSelection(1)
378 groupnames = list(self.controller.file_groups.keys())
379 self.wids['energy_ref'].SetChoices(groupnames)
380 eref = opts.get('energy_ref', 'no_energy_ref')
382 for key, val in self.controller.file_groups.items():
383 if eref in (val, key):
384 self.wids['energy_ref'].SetStringSelection(key)
386 self.wids['e0'].SetValue(opts.get('e0', -1))
387 edge_step = opts.get('edge_step', 1.0)
389 if hasattr(dgroup, 'e0') and opts['atsym'] == '?':
390 atsym, edge = guess_edge(dgroup.e0)
391 opts['atsym'] = atsym
392 opts['edge'] = edge
394 self.wids['step'].SetValue(edge_step)
395 autoset_fs_increment(self.wids['step'], edge_step)
396 for attr in ('pre1', 'pre2', 'norm1', 'norm2'):
397 val = opts.get(attr, None)
398 if val is not None:
399 self.wids[attr].SetValue(val)
401 self.set_nnorm_widget(opts.get('nnorm'))
403 self.wids['energy_shift'].SetValue(opts['energy_shift'])
404 self.wids['nvict'].SetStringSelection("%d" % opts['nvict'])
405 self.wids['show_e0'].SetValue(opts['show_e0'])
406 self.wids['auto_e0'].SetValue(opts['auto_e0'])
407 self.wids['auto_step'].SetValue(opts['auto_step'])
408 self.wids['edge'].SetStringSelection(opts['edge'].title())
409 self.wids['atsym'].SetStringSelection(opts['atsym'].title())
410 self.wids['norm_method'].SetStringSelection(opts['norm_method'].lower())
411 for attr in ('pre1', 'pre2', 'norm1', 'norm2', 'nnorm', 'edge',
412 'atsym', 'step', 'norm_method'):
413 self.wids[attr].Enable()
414 self.wids['show_pre'].SetValue(opts['show_pre'])
415 self.wids['show_norm'].SetValue(opts['show_norm'])
417 self.wids['scale'].Disable()
419 else:
420 self.plotone_op.SetChoices(list(PlotOne_Choices_nonxas.keys()))
421 self.plotsel_op.SetChoices(list(PlotSel_Choices_nonxas.keys()))
423 self.wids['scale'].SetValue(opts['scale'])
424 for attr in ('pre1', 'pre2', 'norm1', 'norm2', 'nnorm', 'edge',
425 'atsym', 'step', 'norm_method'):
426 self.wids[attr].Disable()
427 self.wids['scale'].Enable()
429 frozen = opts.get('is_frozen', False)
430 frozen = getattr(dgroup, 'is_frozen', frozen)
432 self.wids['is_frozen'].SetValue(frozen)
433 self._set_frozen(frozen)
434 wx.CallAfter(self.unset_skip_process)
436 def set_nnorm_widget(self, nnorm=None):
437 nnorm_str = 'auto'
438 if nnorm is not None:
439 try:
440 nnorm = int(nnorm)
441 except ValueError:
442 nnorm = None
444 for k, v in NNORM_CHOICES.items():
445 if v == nnorm:
446 nnorm_str = k
447 self.wids['nnorm'].SetStringSelection(nnorm_str)
449 def unset_skip_process(self):
450 self.skip_process = False
452 def read_form(self):
453 "read form, return dict of values"
454 form_opts = {}
455 form_opts['e0'] = self.wids['e0'].GetValue()
456 form_opts['edge_step'] = self.wids['step'].GetValue()
457 for attr in ('pre1', 'pre2', 'norm1', 'norm2'):
458 val = self.wids[attr].GetValue()
459 if val == 0: val = None
460 form_opts[attr] = val
462 form_opts['energy_shift'] = self.wids['energy_shift'].GetValue()
464 form_opts['nnorm'] = NNORM_CHOICES.get(self.wids['nnorm'].GetStringSelection(), None)
465 form_opts['nvict'] = int(self.wids['nvict'].GetStringSelection())
466 form_opts['plotone_op'] = self.plotone_op.GetStringSelection()
467 form_opts['plotsel_op'] = self.plotsel_op.GetStringSelection()
468 form_opts['plot_voff'] = self.wids['plot_voff'].GetValue()
469 for ch in ('show_e0', 'show_pre', 'show_norm', 'auto_e0', 'auto_step'):
470 form_opts[ch] = self.wids[ch].IsChecked()
472 form_opts['norm_method'] = self.wids['norm_method'].GetStringSelection().lower()
473 form_opts['edge'] = self.wids['edge'].GetStringSelection().title()
474 form_opts['atsym'] = self.wids['atsym'].GetStringSelection().title()
475 form_opts['scale'] = self.wids['scale'].GetValue()
476 form_opts['energy_ref'] = self.wids['energy_ref'].GetStringSelection()
477 return form_opts
479 def onNormMethod(self, evt=None):
480 method = self.wids['norm_method'].GetStringSelection().lower()
481 nnorm = NNORM_CHOICES.get(self.wids['nnorm'].GetStringSelection(), None)
482 nvict = int(self.wids['nvict'].GetStringSelection())
483 self.update_config({'norm_method': method, 'nnorm': nnorm, 'nvict': nvict})
484 if method.startswith('mback'):
485 dgroup = self.controller.get_group()
486 cur_elem = self.wids['atsym'].GetStringSelection()
487 if hasattr(dgroup, 'e0') and cur_elem == 'H':
488 atsym, edge = guess_edge(dgroup.e0)
489 self.wids['edge'].SetStringSelection(edge)
490 self.wids['atsym'].SetStringSelection(atsym)
491 self.update_config({'edge': edge, 'atsym': atsym})
492 time.sleep(0.002)
493 wx.CallAfter(self.onReprocess)
495 def _set_frozen(self, frozen):
496 try:
497 dgroup = self.controller.get_group()
498 dgroup.is_frozen = frozen
499 except:
500 pass
501 for wattr in ('e0', 'step', 'pre1', 'pre2', 'norm1', 'norm2',
502 'nvict', 'nnorm', 'show_e0', 'auto_e0', 'auto_step',
503 'norm_method', 'edge', 'atsym', 'show_pre', 'show_norm'):
504 self.wids[wattr].Enable(not frozen)
506 def onFreezeGroup(self, evt=None):
507 self._set_frozen(evt.IsChecked())
509 def onEnergyRef(self, evt=None):
510 dgroup = self.controller.get_group()
511 eref = self.wids['energy_ref'].GetStringSelection()
512 gname = self.controller.file_groups[eref]
513 dgroup.config.xasnorm['energy_ref'] = eref
514 dgroup.energy_ref = eref
515 self.update_config({'energy_ref': eref}, dgroup=dgroup)
517 def onPlotEither(self, evt=None):
518 if self.last_plot_type == 'multi':
519 self.onPlotSel(evt=evt)
520 else:
521 self.onPlotOne(evt=evt)
523 def onPlotOne(self, evt=None):
524 self.last_plot_type = 'one'
525 self.plot(self.controller.get_group())
526 wx.CallAfter(self.controller.set_focus)
528 def onVoffset(self, evt=None):
529 time.sleep(0.002)
530 wx.CallAfter(self.onPlotSel)
532 def onPlotSel(self, evt=None):
533 newplot = True
534 self.last_plot_type = 'multi'
535 group_ids = self.controller.filelist.GetCheckedStrings()
536 if len(group_ids) < 1:
537 return
538 last_id = group_ids[-1]
540 groupname = self.controller.file_groups[str(last_id)]
541 dgroup = self.controller.get_group(groupname)
543 plot_choices = PlotSel_Choices
544 if not self.is_xasgroup(dgroup):
545 plot_choices = PlotSel_Choices_nonxas
547 erange = Plot_EnergyRanges[self.plot_erange.GetStringSelection()]
548 self.controller.set_plot_erange(erange)
550 ytitle = self.plotsel_op.GetStringSelection()
551 yarray_name = plot_choices[ytitle]
552 ylabel = getattr(plotlabels, yarray_name, ytitle)
553 xlabel = getattr(dgroup, 'plot_xlabel', getattr(plotlabels, 'energy'))
555 if yarray_name == 'norm':
556 norm_method = self.wids['norm_method'].GetStringSelection().lower()
557 if norm_method.startswith('mback'):
558 yarray_name = 'norm_mback'
559 ylabel = "%s (MBACK)" % ylabel
560 elif norm_method.startswith('area'):
561 yarray_name = 'norm_area'
562 ylabel = "%s (Area)" % ylabel
563 voff = self.wids['plot_voff'].GetValue()
564 plot_traces = []
565 newplot = True
566 plotopts = self.controller.get_plot_conf()
567 popts = {'style': 'solid', 'marker': None}
568 popts['linewidth'] = plotopts.pop('linewidth')
569 popts['marksize'] = plotopts.pop('markersize')
570 popts['grid'] = plotopts.pop('show_grid')
571 popts['fullbox'] = plotopts.pop('show_fullbox')
573 for ix, checked in enumerate(group_ids):
574 groupname = self.controller.file_groups[str(checked)]
575 dgroup = self.controller.get_group(groupname)
576 if dgroup is None:
577 continue
578 self.ensure_xas_processed(dgroup)
580 if erange is not None and hasattr(dgroup, 'e0') and 'xmin' not in popts:
581 popts['xmin'] = dgroup.e0 + erange[0]
582 popts['xmax'] = dgroup.e0 + erange[1]
584 trace = {'xdata': dgroup.xdat,
585 'ydata': getattr(dgroup, yarray_name) + ix*voff,
586 'label': dgroup.filename, 'new': newplot}
587 trace.update(popts)
588 plot_traces.append(trace)
589 newplot = False
591 ppanel = self.controller.get_display(stacked=False).panel
592 zoom_limits = get_zoomlimits(ppanel, dgroup)
594 nplot_traces = len(ppanel.conf.traces)
595 nplot_request = len(plot_traces)
596 if nplot_request > nplot_traces:
597 linecolors = ppanel.conf.linecolors
598 ncols = len(linecolors)
599 for i in range(nplot_traces, nplot_request+5):
600 ppanel.conf.init_trace(i, linecolors[i%ncols], 'dashed')
602 #
604 ppanel.plot_many(plot_traces, xlabel=plotlabels.energy, ylabel=ylabel,
605 zoom_limits=zoom_limits, show_legend=True)
606 set_zoomlimits(ppanel, zoom_limits) or ppanel.unzoom_all()
607 ppanel.canvas.draw()
609 wx.CallAfter(self.controller.set_focus)
611 def onAutoNorm(self, evt=None):
612 defaults = self.get_defaultconfig()
613 norm1 = defaults['norm1']
614 norm2 = defaults['norm2']
615 nnorm = 2
616 if (norm2-norm1 < 350): nnorm = 1
617 if (norm2-norm1 < 50): nnorm = 0
619 self.set_nnorm_widget(nnorm)
620 self.wids['norm_method'].SetSelection(0)
621 self.wids['auto_step'].SetValue(1)
622 self.wids['auto_e0'].SetValue(1)
623 self.wids['nvict'].SetSelection(0)
624 for attr in ('pre1', 'pre2', 'norm1', 'norm2'):
625 self.wids[attr].SetValue(defaults[attr])
626 self.onReprocess()
628 def onCopyAuto(self, evt=None):
629 opts = dict(pre1=0, pre2=0, nvict=0, norm1=0, norm2=0,
630 norm_method='polynomial', nnorm=2, auto_e0=1,
631 auto_step=1)
632 for checked in self.controller.filelist.GetCheckedStrings():
633 groupname = self.controller.file_groups[str(checked)]
634 grp = self.controller.get_group(groupname)
635 if grp != self.controller.group and not getattr(grp, 'is_frozen', False):
636 self.update_config(opts, dgroup=grp)
637 self.fill_form(grp)
638 self.process(grp, force=True)
641 def onSaveConfigBtn(self, evt=None):
642 conf = self.get_config()
643 conf.update(self.read_form())
644 # self.set_defaultconfig(conf)
646 def onCopyParam(self, name=None, evt=None):
647 conf = self.get_config()
648 form = self.read_form()
649 conf.update(form)
650 dgroup = self.controller.get_group()
651 self.update_config(conf)
652 self.fill_form(dgroup)
653 opts = {}
654 name = str(name)
655 def copy_attrs(*args):
656 for a in args:
657 opts[a] = conf[a]
658 if name == 'all':
659 copy_attrs('e0', 'show_e0', 'auto_e0', 'edge_step',
660 'auto_step', 'energy_shift', 'pre1', 'pre2',
661 'nvict', 'atsym', 'edge', 'norm_method', 'nnorm',
662 'norm1', 'norm2', 'energy_ref')
663 elif name == 'xas_e0':
664 copy_attrs('e0', 'show_e0', 'auto_e0')
665 elif name == 'xas_step':
666 copy_attrs('edge_step', 'auto_step')
667 elif name == 'energy_shift':
668 copy_attrs('energy_shift')
669 elif name == 'xas_pre':
670 copy_attrs('pre1', 'pre2', 'nvict', 'show_pre')
671 elif name == 'atsym':
672 copy_attrs('atsym', 'edge')
673 elif name == 'xas_norm':
674 copy_attrs('norm_method', 'nnorm', 'norm1', 'norm2', 'show_norm')
675 elif name == 'energy_ref':
676 copy_attrs('energy_ref')
677 for checked in self.controller.filelist.GetCheckedStrings():
678 groupname = self.controller.file_groups[str(checked)]
679 grp = self.controller.get_group(groupname)
680 if grp != self.controller.group and not getattr(grp, 'is_frozen', False):
681 self.update_config(opts, dgroup=grp)
682 for key, val in opts.items():
683 if hasattr(grp, key):
684 setattr(grp, key, val)
685 self.fill_form(grp)
686 self.process(grp, force=True)
688 def onAuto_XASE0(self, evt=None):
689 if evt.IsChecked():
690 dgroup = self.controller.get_group()
691 find_e0(dgroup)
692 self.update_config({'e0': dgroup.e0})
693 time.sleep(0.002)
694 wx.CallAfter(self.onReprocess)
696 def onSet_XASE0(self, evt=None, value=None):
697 "handle setting auto e0 / show e0"
698 auto_e0 = self.wids['auto_e0'].GetValue()
699 self.update_config({'e0': self.wids['e0'].GetValue(),
700 'auto_e0':self.wids['auto_e0'].GetValue()})
701 time.sleep(0.002)
702 wx.CallAfter(self.onReprocess)
704 def onSet_XASE0Val(self, evt=None, value=None):
705 "handle setting e0"
706 self.wids['auto_e0'].SetValue(0)
707 self.update_config({'e0': self.wids['e0'].GetValue(),
708 'auto_e0':self.wids['auto_e0'].GetValue()})
709 time.sleep(0.002)
710 wx.CallAfter(self.onReprocess)
712 def onSet_EnergyShift(self, evt=None, value=None):
713 conf = self.get_config()
714 if conf['auto_energy_shift']:
715 eshift = self.wids['energy_shift'].GetValue()
716 dgroup = self.controller.get_group()
717 _eref = getattr(dgroup, 'energy_ref', '<;no eref;>')
718 _gname = dgroup.groupname
719 self.stale_groups = []
720 for fname, gname in self.controller.file_groups.items():
721 this = self.controller.get_group(gname)
722 if _gname != gname and _eref == getattr(this, 'energy_ref', None):
723 this.energy_shift = this.config.xasnorm['energy_shift'] = eshift
724 self.stale_groups.append(this)
726 wx.CallAfter(self.onReprocess)
728 def onSet_XASStep(self, evt=None, value=None):
729 "handle setting edge step"
730 edge_step = self.wids['step'].GetValue()
731 if edge_step < 0:
732 self.wids['step'].SetValue(abs(edge_step))
733 self.wids['auto_step'].SetValue(0)
734 self.update_config({'edge_step': abs(edge_step), 'auto_step': False})
735 autoset_fs_increment(self.wids['step'], abs(edge_step))
736 time.sleep(0.01)
737 wx.CallAfter(self.onReprocess)
739 def onSet_Scale(self, evt=None, value=None):
740 "handle setting non-XAFS scale value"
741 scale = self.wids['scale'].GetValue()
742 if scale < 0:
743 self.wids['scale'].SetValue(abs(scale))
744 self.update_config({'scale': self.wids['scale'].GetValue()})
745 autoset_fs_increment(self.wids['scale'], abs(scale))
746 time.sleep(0.01)
747 wx.CallAfter(self.onReprocess)
749 def onSet_Ranges(self, evt=None, **kws):
750 conf = {}
751 for attr in ('pre1', 'pre2', 'norm1', 'norm2'):
752 conf[attr] = self.wids[attr].GetValue()
753 self.update_config(conf)
754 time.sleep(0.01)
755 wx.CallAfter(self.onReprocess)
757 def pin_callback(self, opt='__', xsel=None, relative_e0=True, **kws):
758 """
759 get last selected point from a specified plot window
760 and fill in the value for the widget defined by `opt`.
762 by default it finds the latest cursor position from the
763 cursor history of the first 20 plot windows.
764 """
765 if xsel is None or opt not in self.wids:
766 return
767 e0 = self.wids['e0'].GetValue()
768 if opt == 'e0':
769 self.wids['e0'].SetValue(xsel)
770 self.wids['auto_e0'].SetValue(0)
771 elif opt in ('pre1', 'pre2', 'norm1', 'norm2'):
772 self.wids[opt].SetValue(xsel-e0)
773 time.sleep(0.01)
774 wx.CallAfter(self.onReprocess)
776 def onReprocess(self, evt=None, value=None, **kws):
777 "handle request reprocess"
778 if self.skip_process:
779 return
780 try:
781 dgroup = self.controller.get_group()
782 except TypeError:
783 return
784 if not hasattr(dgroup.config, self.configname):
785 return
786 form = self.read_form()
787 self.process(dgroup=dgroup)
788 if self.stale_groups is not None:
789 for g in self.stale_groups:
790 self.process(dgroup=g, force=True)
791 self.stale_groups = None
792 self.onPlotEither()
795 def process(self, dgroup=None, force_mback=False, force=False, use_form=True, **kws):
796 """ handle process (pre-edge/normalize) of XAS data from XAS form
797 """
799 if self.skip_process and not force:
800 return
801 if dgroup is None:
802 dgroup = self.controller.get_group()
803 if dgroup is None:
804 return
806 self.skip_process = True
808 conf = self.get_config(dgroup)
809 form = self.read_form()
810 if not use_form:
811 form.update(self.get_defaultconfig())
813 form['group'] = dgroup.groupname
814 groupnames = list(self.controller.file_groups.keys())
815 self.wids['energy_ref'].SetChoices(groupnames)
816 eref_sel = self.wids['energy_ref'].GetStringSelection()
817 for key, val in self.controller.file_groups.items():
818 if eref_sel in (val, key):
819 self.wids['energy_ref'].SetStringSelection(key)
821 if not self.is_xasgroup(dgroup):
822 self.skip_process = False
823 dgroup.mu = dgroup.ydat * 1.0
824 opts = {'group': dgroup.groupname, 'scale': conf.get('scale', 1.0)}
825 self.larch_eval("{group:s}.scale = {scale:.8f}".format(**opts))
826 self.larch_eval("{group:s}.norm = {scale:.8f}*{group:s}.ydat".format(**opts))
827 return
829 en_units = getattr(dgroup, 'energy_units', None)
830 if en_units is None:
831 en_units = guess_energy_units(dgroup.energy)
833 if en_units != 'eV':
834 mono_dspace = getattr(dgroup, 'mono_dspace', 1)
835 dlg = EnergyUnitsDialog(self.parent, dgroup.energy,
836 unitname=en_units,
837 dspace=mono_dspace)
838 res = dlg.GetResponse()
839 dlg.Destroy()
840 if res.ok:
841 en_units = res.units
842 dgroup.mono_dspace = res.dspace
843 dgroup.xdat = dgroup.energy = res.energy
844 dgroup.energy_units = en_units
846 if hasattr(dgroup, 'e0') and form['atsym'] == '?':
847 form['atsym'], form['edge'] = guess_edge(dgroup.e0)
849 dgroup.atsym = form['atsym']
850 dgroup.edge = form['edge']
852 cmds = []
853 # test whether the energy shift is 0 or is different from the current energy shift:
854 ediff = 8.42e14 # just a huge energy step/shift
855 eshift_current = getattr(dgroup, 'energy_shift', ediff)
856 eshift = form.get('energy_shift', ediff)
857 e1 = getattr(dgroup, 'energy', [ediff])
858 e2 = getattr(dgroup, 'energy_orig', None)
860 if (not isinstance(e2, np.ndarray) or (len(e1) != len(e2))):
861 cmds.append("{group:s}.energy_orig = {group:s}.energy[:]")
863 if (isinstance(e1, np.ndarray) and isinstance(e2, np.ndarray) and
864 len(e1) == len(e2)):
865 ediff = (e1-e2).min()
867 if abs(eshift-ediff) > 1.e-5 or abs(eshift-eshift_current) > 1.e-5:
868 if abs(eshift) > 1e15: eshift = 0.0
869 cmds.extend(["{group:s}.energy_shift = {eshift:.4f}",
870 "{group:s}.energy = {group:s}.xdat = {group:s}.energy_orig + {group:s}.energy_shift"])
872 if len(cmds) > 0:
873 self.larch_eval(('\n'.join(cmds)).format(group=dgroup.groupname, eshift=eshift))
875 e0 = form['e0']
876 edge_step = form['edge_step']
878 copts = [dgroup.groupname]
879 if not form['auto_e0']:
880 if e0 < max(dgroup.energy) and e0 > min(dgroup.energy):
881 copts.append("e0=%.4f" % float(e0))
883 if not form['auto_step']:
884 copts.append("step=%s" % gformat(float(edge_step)))
886 for attr in ('pre1', 'pre2', 'nvict', 'nnorm', 'norm1', 'norm2'):
887 if form[attr] is None or form[attr] == 'auto':
888 copts.append("%s=None" % attr)
889 else:
890 fmt = "%s=%d" if attr in ('nvict', 'nnorm') else "%s=%.2f"
891 copts.append(fmt % (attr, form[attr]))
893 self.larch_eval("pre_edge(%s)" % (', '.join(copts)))
894 self.larch_eval("{group:s}.norm_poly = 1.0*{group:s}.norm".format(**form))
895 if not hasattr(dgroup, 'e0'):
896 self.skip_process = False
897 dgroup.mu = dgroup.ydat * 1.0
898 opts = {'group': dgroup.groupname, 'scale': conf.get('scale', 1.0)}
899 return
901 norm_method = form['norm_method'].lower()
902 form['normmeth'] = 'poly'
904 dgroup.journal.add_ifnew('normalization_method', norm_method)
906 if force_mback or norm_method.startswith('mback'):
907 form['normmeth'] = 'mback'
908 copts = [dgroup.groupname]
909 copts.append("z=%d" % atomic_number(form['atsym']))
910 copts.append("edge='%s'" % form['edge'])
911 for attr in ('pre1', 'pre2', 'nvict', 'nnorm', 'norm1', 'norm2'):
912 if form[attr] is None:
913 copts.append("%s=None" % attr)
914 else:
915 copts.append("%s=%.2f" % (attr, form[attr]))
916 self.larch_eval("mback_norm(%s)" % (', '.join(copts)))
918 if form['auto_step']:
919 norm_expr = """{group:s}.norm = 1.0*{group:s}.norm_{normmeth:s}
920{group:s}.edge_step = 1.0*{group:s}.edge_step_{normmeth:s}"""
921 self.larch_eval(norm_expr.format(**form))
922 else:
923 norm_expr = """{group:s}.norm = 1.0*{group:s}.norm_{normmeth:s}
924{group:s}.norm *= {group:s}.edge_step_{normmeth:s}/{edge_step:.8f}"""
925 self.larch_eval(norm_expr.format(**form))
927 if norm_method.startswith('area'):
928 form['normmeth'] = 'area'
929 expr = """{group:s}.norm = 1.0*{group:s}.norm_{normmeth:s}
930{group:s}.edge_step = 1.0*{group:s}.edge_step_{normmeth:s}"""
931 self.larch_eval(expr.format(**form))
934 if form['auto_e0'] and hasattr(dgroup, 'e0'):
935 self.wids['e0'].SetValue(dgroup.e0)
936 if form['auto_step'] and hasattr(dgroup, 'edge_step'):
937 self.wids['step'].SetValue(dgroup.edge_step)
938 autoset_fs_increment(self.wids['step'], dgroup.edge_step)
940 if hasattr(dgroup, 'e0') and (conf.get('atsym', '?') == '?'):
941 atsym, edge = guess_edge(dgroup.e0)
942 conf['atsym'] = dgroup.atsym = atsym
943 conf['edge'] = dgroup.edge = edge
945 self.wids['atsym'].SetStringSelection(dgroup.atsym)
946 self.wids['edge'].SetStringSelection(dgroup.edge)
948 self.set_nnorm_widget(dgroup.pre_edge_details.nnorm)
949 for attr in ('e0', 'edge_step'):
950 conf[attr] = getattr(dgroup, attr)
951 for attr in ('pre1', 'pre2', 'norm1', 'norm2'):
952 conf[attr] = val = getattr(dgroup.pre_edge_details, attr, None)
953 if val is not None:
954 self.wids[attr].SetValue(val)
956 if hasattr(dgroup, 'mback_params'): # from mback
957 conf['atsym'] = getattr(dgroup.mback_params, 'atsym')
958 conf['edge'] = getattr(dgroup.mback_params, 'edge')
959 self.update_config(conf, dgroup=dgroup)
960 wx.CallAfter(self.unset_skip_process)
962 def get_plot_arrays(self, dgroup):
963 lab = plotlabels.norm
964 if dgroup is None:
965 return
967 dgroup.plot_y2label = None
968 dgroup.plot_xlabel = plotlabels.energy
969 dgroup.plot_yarrays = [('norm', PLOTOPTS_1, lab)]
971 if not self.is_xasgroup(dgroup):
972 pchoice = PlotOne_Choices_nonxas[self.plotone_op.GetStringSelection()]
973 dgroup.plot_xlabel = 'x'
974 dgroup.plot_ylabel = 'y'
975 dgroup.plot_yarrays = [('ydat', PLOTOPTS_1, 'ydat')]
976 dgroup.dmude = np.gradient(dgroup.ydat)/np.gradient(dgroup.xdat)
977 dgroup.d2mude = np.gradient(dgroup.dmude)/np.gradient(dgroup.xdat)
978 if not hasattr(dgroup, 'scale'):
979 dgroup.scale = 1.0
981 dgroup.norm = dgroup.ydat*dgroup.scale
982 if pchoice == 'dmude':
983 dgroup.plot_ylabel = 'dy/dx'
984 dgroup.plot_yarrays = [('dmude', PLOTOPTS_1, 'dy/dx')]
985 elif pchoice == 'd2mude':
986 dgroup.plot_ylabel = 'd2y/dx2'
987 dgroup.plot_yarrays = [('d2mude', PLOTOPTS_1, 'd2y/dx')]
988 elif pchoice == 'norm':
989 dgroup.plot_ylabel = 'scaled y'
990 dgroup.plot_yarrays = [('norm', PLOTOPTS_1, 'y/scale')]
991 elif pchoice == 'norm+dmude':
992 lab = plotlabels.norm
993 dgroup.plot_y2label = 'dy/dx'
994 dgroup.plot_yarrays = [('ydat', PLOTOPTS_1, 'y'),
995 ('dmude', PLOTOPTS_D, 'dy/dx')]
996 elif pchoice == 'norm+d2mude':
997 lab = plotlabels.norm
998 dgroup.plot_y2label = 'd2y/dx2'
999 dgroup.plot_yarrays = [('ydat', PLOTOPTS_1, 'y'),
1000 ('d2normde', PLOTOPTS_D, 'd2y/dx2')]
1001 return
1003 req_attrs = ['e0', 'norm', 'dmude', 'd2mude', 'pre_edge']
1005 pchoice = PlotOne_Choices[self.plotone_op.GetStringSelection()]
1007 if pchoice in ('mu', 'norm', 'i0', 'flat', 'dmude', 'd2mude'):
1008 lab = getattr(plotlabels, pchoice)
1009 dgroup.plot_yarrays = [(pchoice, PLOTOPTS_1, lab)]
1011 elif pchoice == 'prelines':
1012 lab = plotlabels.mu
1013 dgroup.plot_yarrays = [('mu', PLOTOPTS_1, plotlabels.mu),
1014 ('pre_edge', PLOTOPTS_2, 'pre edge'),
1015 ('post_edge', PLOTOPTS_2, 'post edge')]
1017 elif pchoice == 'norm+d2mude':
1018 lab = plotlabels.norm
1019 dgroup.plot_y2label = lab2 = plotlabels.d2mude
1020 dgroup.plot_yarrays = [('norm', PLOTOPTS_1, lab),
1021 ('d2mude', PLOTOPTS_D, lab2)]
1023 elif pchoice == 'norm+dmude':
1024 lab = plotlabels.norm
1025 dgroup.plot_y2label = lab2 = plotlabels.dmude
1026 dgroup.plot_yarrays = [('norm', PLOTOPTS_1, lab),
1027 ('dmude', PLOTOPTS_D, lab2)]
1028 elif pchoice == 'norm+i0':
1029 lab = plotlabels.norm
1030 dgroup.plot_y2label = lab2 = plotlabels.i0
1031 dgroup.plot_yarrays = [('ydat', PLOTOPTS_1, lab),
1032 ('i0', PLOTOPTS_D, lab2)]
1033 elif pchoice == 'norm+flat':
1034 lab = plotlabels.norm
1035 dgroup.plot_y2label = lab2 = plotlabels.flat
1036 dgroup.plot_yarrays = [('ydat', PLOTOPTS_1, lab),
1037 ('flat', PLOTOPTS_D, lab2)]
1038 elif pchoice == 'mback_norm':
1039 req_attrs.append('mback_norm')
1040 lab = plotlabels.mu
1041 if not hasattr(dgroup, 'mback_mu'):
1042 self.process(dgroup=dgroup, force_mback=True)
1043 dgroup.plot_yarrays = [('mu', PLOTOPTS_1, lab),
1044 ('mback_mu', PLOTOPTS_2, r'tabulated $\mu(E)$')]
1046 elif pchoice == 'mback_poly':
1047 req_attrs.append('mback_norm')
1048 lab = plotlabels.norm
1049 if not hasattr(dgroup, 'mback_mu'):
1050 self.process(dgroup=dgroup, force_mback=True)
1051 dgroup.plot_yarrays = [('norm_mback', PLOTOPTS_1, 'mback'),
1052 ('norm_poly', PLOTOPTS_2, 'polynomial')]
1054 elif pchoice == 'area_norm':
1055 dgroup.plot_yarrays = [('norm_area', PLOTOPTS_1, 'area'),
1056 ('norm_poly', PLOTOPTS_2, 'polynomial')]
1058 dgroup.plot_ylabel = lab
1059 needs_proc = False
1060 for attr in req_attrs:
1061 needs_proc = needs_proc or (not hasattr(dgroup, attr))
1063 if needs_proc:
1064 self.process(dgroup=dgroup, force=True)
1066 y4e0 = dgroup.ydat = getattr(dgroup, dgroup.plot_yarrays[0][0], dgroup.mu)
1067 dgroup.plot_extras = []
1069 popts = {'marker': 'o', 'markersize': 5,
1070 'label': '_nolegend_',
1071 'markerfacecolor': '#888',
1072 'markeredgecolor': '#A00'}
1074 if self.wids['show_e0'].IsChecked():
1075 ie0 = index_of(dgroup.energy, dgroup.e0)
1076 dgroup.plot_extras.append(('marker', dgroup.e0, y4e0[ie0], popts))
1078 if self.wids['show_pre'].IsChecked() or self.wids['show_norm'].IsChecked():
1079 popts['markersize'] = 4
1080 wids = []
1081 if self.wids['show_pre'].IsChecked(): wids.extend(['pre1', 'pre2'])
1082 if self.wids['show_norm'].IsChecked(): wids.extend(['norm1', 'norm2'])
1083 for wid in wids:
1084 val = self.wids[wid].GetValue()
1085 ival = min(len(y4e0)-1, index_of(dgroup.energy, dgroup.e0 + val))
1086 dgroup.plot_extras.append(('marker', dgroup.e0+val, y4e0[ival], popts))
1089 def plot(self, dgroup, title=None, plot_yarrays=None, yoff=0,
1090 delay_draw=True, multi=False, new=True, with_extras=True, **kws):
1092 if self.skip_plotting:
1093 return
1094 ppanel = self.controller.get_display(stacked=False).panel
1096 plotcmd = ppanel.oplot
1097 if new:
1098 plotcmd = ppanel.plot
1100 erange = Plot_EnergyRanges[self.plot_erange.GetStringSelection()]
1101 self.controller.set_plot_erange(erange)
1103 groupname = getattr(dgroup, 'groupname', None)
1104 if groupname is None:
1105 return
1107 if not hasattr(dgroup, 'xdat'):
1108 print("Cannot plot group ", groupname)
1110 if ((getattr(dgroup, 'plot_yarrays', None) is None or
1111 getattr(dgroup, 'energy', None) is None or
1112 getattr(dgroup, 'mu', None) is None or
1113 getattr(dgroup, 'e0', None) is None or
1114 getattr(dgroup, 'dmude', None) is None or
1115 getattr(dgroup, 'd2mude', None) is None or
1116 getattr(dgroup, 'norm', None) is None)):
1117 self.process(dgroup=dgroup)
1118 self.get_plot_arrays(dgroup)
1120 if plot_yarrays is None and hasattr(dgroup, 'plot_yarrays'):
1121 plot_yarrays = dgroup.plot_yarrays
1123 popts = self.controller.get_plot_conf()
1124 popts.update(kws)
1125 popts['grid'] = popts.pop('show_grid')
1126 popts['fullbox'] = popts.pop('show_fullbox')
1128 path, fname = os.path.split(dgroup.filename)
1129 if 'label' not in popts:
1130 popts['label'] = dgroup.plot_ylabel
1132 zoom_limits = get_zoomlimits(ppanel, dgroup)
1134 if erange is not None and hasattr(dgroup, 'e0'):
1135 popts['xmin'] = dgroup.e0 + erange[0]
1136 popts['xmax'] = dgroup.e0 + erange[1]
1138 popts['xlabel'] = dgroup.plot_xlabel
1139 popts['ylabel'] = dgroup.plot_ylabel
1140 if getattr(dgroup, 'plot_y2label', None) is not None:
1141 popts['y2label'] = dgroup.plot_y2label
1143 plot_choices = PlotSel_Choices
1144 if not self.is_xasgroup(dgroup):
1145 plot_choices = PlotSel_Choices_nonxas
1147 if multi:
1148 ylabel = self.plotsel_op.GetStringSelection()
1149 yarray_name = plot_choices[ylabel]
1151 if self.is_xasgroup(dgroup):
1152 ylabel = getattr(plotlabels, yarray_name, ylabel)
1153 popts['ylabel'] = ylabel
1155 plot_extras = None
1156 if new:
1157 if title is None:
1158 title = fname
1159 plot_extras = getattr(dgroup, 'plot_extras', None)
1161 popts['title'] = title
1162 popts['show_legend'] = len(plot_yarrays) > 1
1163 narr = len(plot_yarrays) - 1
1165 _linewidth = popts['linewidth']
1167 for i, pydat in enumerate(plot_yarrays):
1168 yaname, yopts, yalabel = pydat
1169 popts.update(yopts)
1170 if yalabel is not None:
1171 popts['label'] = yalabel
1172 linewidht = _linewidth
1173 if 'linewidth' in popts:
1174 linewidth = popts.pop('linewidth')
1175 popts['delay_draw'] = delay_draw
1176 if yaname == 'norm_mback' and not hasattr(dgroup, yaname):
1177 self.process(dgroup=dgroup, force=True, force_mback=True)
1178 if yaname == 'i0' and not hasattr(dgroup, yaname):
1179 dgroup.i0 = np.ones(len(dgroup.xdat))
1180 plotcmd(dgroup.xdat, getattr(dgroup, yaname)+yoff, linewidth=linewidth, **popts)
1181 plotcmd = ppanel.oplot
1183 if with_extras and plot_extras is not None:
1184 axes = ppanel.axes
1185 for etype, x, y, opts in plot_extras:
1186 if etype == 'marker':
1187 xpopts = {'marker': 'o', 'markersize': 5,
1188 'label': '_nolegend_',
1189 'markerfacecolor': 'red',
1190 'markeredgecolor': '#884444'}
1191 xpopts.update(opts)
1192 axes.plot([x], [y], **xpopts)
1193 elif etype == 'vline':
1194 xpopts = {'ymin': 0, 'ymax': 1.0,
1195 'label': '_nolegend_',
1196 'color': '#888888'}
1197 xpopts.update(opts)
1198 axes.axvline(x, **xpopts)
1200 # set_zoomlimits(ppanel, zoom_limits)
1201 ppanel.reset_formats()
1202 set_zoomlimits(ppanel, zoom_limits)
1203 ppanel.conf.unzoom(full=True, delay_draw=False)