Coverage for larch/wxxas/config.py: 0%
75 statements
« prev ^ index » next coverage.py v7.6.0, created at 2024-10-16 21:04 +0000
« prev ^ index » next coverage.py v7.6.0, created at 2024-10-16 21:04 +0000
1from collections import namedtuple
3import wxmplot
5from larch.site_config import get_homedir
6from larch.xafs.xafsutils import FT_WINDOWS
7from larch.utils.physical_constants import ATOM_SYMS
9ATSYMS = ['?'] + ATOM_SYMS[:98]
10EDGES = ['K', 'L3', 'L2', 'L1', 'M5', 'M4', 'M3', 'N7']
11OLDCONF_FILE = 'xas_viewer.conf'
12CONF_FILE = 'larix.conf'
14wxmplot.config.Themes['fivethirtyeight'].update({'legend.fontsize': 10,
15 'xtick.labelsize': 9,
16 'ytick.labelsize': 9,
17 'axes.labelsize': 9,
18 'axes.titlesize': 13})
20ARRAYS = {'mu': 'Raw \u03BC(E)',
21 'norm': 'Normalized \u03BC(E)',
22 'flat': 'Flattened \u03BC(E)',
23 'norm+flat': 'Normalized + Flattened \u03BC(E)',
24 'prelines': '\u03BC(E) + Pre-/Post-edge',
25 'mback_norm': '\u03BC(E) + MBACK \u03BC(E)',
26 'mback_poly': 'MBACK + Poly Normalized',
27 'i0': 'I0(E)',
28 'norm+i0': 'Normalized \u03BC(E) + I0(E)',
29 'dmude': 'd\u03BC(E)/dE ',
30 'norm+dmude': 'Normalized \u03BC(E) + d\u03BC(E)/dE',
31 'd2mude': 'd^2\u03BC(E)/dE^2',
32 'norm+d2mude': 'Normalized \u03BC(E) + d^2\u03BC(E)/dE^2',
33 'deconv': 'Deconvolved \u03BC(E)',
34 'chi': '\u03c7(k)',
35 'chi0': '\u03c7(k)',
36 'chi1': 'k \u03c7(k)',
37 'chi2': 'k^2 \u03c7(k)',
38 'chi3': 'k^3 \u03c7(k)',
39 'chir_mag': '|\u03c7(R)|',
40 'chir_re': 'Re[\u03c7(R)]',
41 'chir_mag+chir_re': '|\u03c7(R)| + Re[\u03c7(R)]',
42 'chir_re_chir_im': 'Re[\u03c7(R)] + Im[\u03c7(R)]',
43 'chiq': 'Filtered \u03c7(k)',
44 'noplot': '<no plot>',
45 }
47# wavelet = 'EXAFS wavelet'
49FT_WINDOWS_AUTO = ['<Auto>']
50FT_WINDOWS_AUTO.extend(FT_WINDOWS)
53def make_array_choice(opts):
54 """make (ordered) dict of {Array Description: varname}"""
55 out = {}
56 for n in opts:
57 if n in ARRAYS:
58 out[ARRAYS[n]] = n
59 return out
62Linear_ArrayChoices = make_array_choice(['norm', 'flat', 'dmude', 'chi0', 'chi1', 'chi2'])
63PrePeak_ArrayChoices = make_array_choice(['norm', 'flat', 'deconv', 'mu'])
64Regress_Choices = ['Partial Least Squares', 'LassoLars']
66PlotWindowChoices = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
68NNORM_CHOICES = {'constant':0, 'linear':1, 'quadratic':2, 'cubic':3}
69NNORM_STRINGS = {int(v): k for k, v in NNORM_CHOICES.items()}
71NORM_METHODS = ('polynomial', 'mback')
73ATHENA_CLAMPNAMES = {'none': 0, 'slight': 1, 'weak': 5, 'medium': 20,
74 'strong': 100, 'rigid': 500}
77Feffit_KWChoices = {'1': '1', '2': '2', '3': '3',
78 '2 and 3': '[2, 3]',
79 '1, 2, and 3': '[2, 1, 3]'}
81Feffit_SpaceChoices = {'R space':'r', 'k space':'k', 'wavelet': 'w'}
82Feffit_PlotChoices = {'K and R space': 'k+r', 'R space only': 'r'}
84Valid_DataTypes = ('string', 'float', 'int', 'bool', 'choice', 'path')
87AnalysisTab = namedtuple('AnalysisTab', ('title', 'constructor', 'desc'))
89LARIX_PANELS = {
90 'xydata':
91 AnalysisTab('XY Data', 'larch.wxxas.xydata_panel.XYDataPanel',
92 'Read and Manipulate XY Data from Column Data files'),
93 'xasnorm':
94 AnalysisTab('XAS Normalization', 'larch.wxxas.xasnorm_panel.XASNormPanel',
95 'Normalization and Pre-edge subtraction for XANES and EXAFS'),
96 'prepeaks':
97 AnalysisTab('Pre-edge Peaks', 'larch.wxxas.prepeak_panel.PrePeakPanel',
98 'Curve Fitting for XANES Pre-edge Peaks'),
99 'pca':
100 AnalysisTab('XAS PCA', 'larch.wxxas.pca_panel.PCAPanel',
101 'Principal Component Analysis for XANES and EXAFS'),
102 'lincombo':
103 AnalysisTab('XAS Linear Combo', 'larch.wxxas.lincombo_panel.LinearComboPanel',
104 'Linear Combination Analysis for XANES and EXAFS'),
105 'regression':
106 AnalysisTab('XAS Regression', 'larch.wxxas.regress_panel.RegressionPanel',
107 'Linear Regression and Feature Selection for XANES and EXAFS'),
108 'exafs':
109 AnalysisTab('EXAFS', 'larch.wxxas.exafs_panel.EXAFSPanel',
110 'EXAFS Background Subtraction and Fourier Transforms'),
111 'feffit':
112 AnalysisTab('FEFF Fitting', 'larch.wxxas.feffit_panel.FeffitPanel',
113 'EXAFS Path Fitting with FEFF calculations'),
114}
116LARIX_MODES = {
117 'all': ('All', [k for k in LARIX_PANELS]),
118 'xydata': ('General XY Data Visualization and Fitting', ('xydata', 'lmfit')),
119 'xas': ('XANES and EXAFS', ('xasnorm', 'prepeaks', 'pca', 'lincombo', 'exafs', 'feffit')),
120 'exafs': ('EXAFS only', ('xasnorm', 'exafs', 'feffit')),
121 'xanes': ('XANES only', ('xasnorm', 'prepeaks', 'pca', 'lincombo')),
122 'xrf': ('XRF Mapping and Analysis', ('maproi', 'mapareas', 'maptomo', 'mapxrf')),
123 'xrd1d': ('XRD 1D', ('xrd1d', )),
124 }
126class CVar:
127 """configuration variable"""
128 def __init__(self, name, value, dtype, choices=None, desc='a variable',
129 min=None, max=None, step=1):
130 self.name = name
131 self.value = value
132 self.dtype = dtype
133 self.choices = choices
134 self.desc = desc
135 self.min = min
136 self.max = max
137 self.step = step
139 if dtype not in Valid_DataTypes:
140 raise ValueError(f"unknown configuration type '{dtype}' for '{name}'")
142 if dtype == 'choice' and self.choices is None:
143 raise ValueError(f"choice configuration type must have choices for '{name}'")
145 def __repr__(self):
146 return f"CVar('{self.name}', {self.value!r}, '{self.dtype}')"
148##
149## sections
150##
151CONF_SECTIONS = {k:v.desc for k, v in LARIX_PANELS.items()}
152CONF_SECTIONS.update({'main': 'Main program configuration',
153 'pin': 'Pin icon to select points from plots',
154 'plot': 'General Plotting',
155 'autosave': 'Automatic saving of Session files',
156 })
158main = [CVar('chdir_on_fileopen', True, 'bool', desc='whether to change working directory when opening a file'),
159 CVar('workdir', get_homedir(), 'path', desc='starting working directory'),
160 CVar('use_last_workdir', True, 'bool', desc='whehter to use the working directory of the last session\nor always start in workdir'),
161 ]
163autosave = [CVar('savetime', 900, 'int', min=1, step=30, desc='time (in sec) between auto-saving Session files'),
164 CVar('nhistory', 5, 'int', min=0, desc='number of auto-saved Session files to keep per session'),
165 CVar('maxfiles', 10, 'int', min=0, desc='maximum number of auto-saved Session files to keep from all sessions'),
166 CVar('fileroot', 'autosave', 'string', desc='filename prefix for auto-saved Session files')]
168pin = [CVar('style', 'pin first', 'choice', choices=['pin first', 'plot first'],
169 desc='whether to click on pin first, then plot or plot first, then pin'),
170 CVar('min_time', 2.0, 'float', min=0, max=60,
171 desc='minimum time (seconds) between clicking on the pin and reporting a value,\nallowing multiple clicks on the plot in that time'),
172 CVar('max_time', 15.0, 'float', min=1, max=300,
173 desc='maximum time (seconds) after clicking on the pin to click on plot.\nWill report last saved value')]
175plot = [CVar('theme', 'light', 'choice', choices=list(wxmplot.config.Themes.keys()),
176 desc='plotting theme for colors and "look and feel"'),
177 CVar('height', 550, 'int', min=100, desc='height of main plot window (in pixels)'),
178 CVar('width', 600, 'int', min=100, desc='width of main plot window (in pixels)'),
179 CVar('linewidth', 3.0, 'float', min=0, step=0.5, desc='line width for each trace (in pixels)'),
180 CVar('markersize', 4.0, 'float', min=0, step=0.5, desc='size of plot markers (in pixels)'),
181 CVar('show_grid', True, 'bool', desc='whether to show grid lines'),
182 CVar('show_fullbox', True, 'bool', desc='whether to show a full box around plot,\nor only left and bottom axes'),
183 ]
186exafs = [CVar('rbkg', 1.0, 'float', min=0, step=0.1, max=10, desc='R value separating background from EXAFS signal'),
187 CVar('bkg_kmin', 0.0, 'float', min=0, step=0.1, max=10, desc='k min for background subtraction'),
188 CVar('bkg_kmax', -1, 'float', min=-1, step=0.1, desc='k max for background subtraction\n(use -1 for "auto")'),
189 CVar('bkg_kweight', 1, 'float', min=0, step=1, max=10, desc='k weight for background subtraction'),
190 CVar('bkg_clamplo', 1, 'float', min=0, step=5, desc='low-k clamp for background subtraction'),
191 CVar('bkg_clamphi', 20, 'float', min=0, step=5, desc='high-k clamp for background subtraction'),
192 CVar('fft_kmin', 2.0, 'float', min=0, step=0.1, max=50, desc='k min for EXAFS Fourier transform'),
193 CVar('fft_kmax', -1, 'float', min=-1, step=0.1, desc='k max for EXAFS Fourier transform\n(use -1 for "auto")'),
194 CVar('fft_kweight', 2, 'float', min=0, step=1, max=10, desc='k weight for EXAFS Fourier transform'),
195 CVar('fft_dk', 4, 'float', min=0, step=0.1, desc='window parameter for k->R EXAFS Fourier transform'),
196 CVar('fft_kwindow', 'Kaiser-Bessel', 'choice', choices=FT_WINDOWS, desc='window type for k->R EXAFS Fourier transform'),
197 CVar('fft_rmin', -1, 'float', min=-1, step=0.1, max=50, desc='R min for EXAFS Back Fourier transform\n(use -1 for "use rbkg")'),
198 CVar('fft_rmax', 5.0, 'float', min=0, step=0.1, desc='k max for EXAFS Back Fourier transform'),
199 CVar('fft_dr', 0.25, 'float', min=0, step=0.05, desc='window parameter for EXAFS Back Fourier transform'),
200 CVar('fft_rwindow', 'Hanning', 'choice', choices=FT_WINDOWS, desc='window type for EXAFS Back Fourier transform'),
201 CVar('fft_rmaxout', 12.0, 'float', min=0, step=0.5, desc='maximum output R value for EXAFS Fourier transform'),
202 CVar('plot_rmax', 8.0, 'float', min=0, step=0.5, desc='maximum R value for EXAFS chi(R) plots')]
205feffit = [CVar('plot_paths', True, 'bool', desc='Whether to plot individual paths in results for Feff fitting'),
206 CVar('fit_kwstring', '2', 'choice', choices=list(Feffit_KWChoices.keys()),
207 desc='k weight to use for Feff fitting'),
208 CVar('fit_space', 'R', 'choice', choices=list(Feffit_SpaceChoices.keys()),
209 desc='Fourier space to use for Feff fitting'),
210 CVar('fit_plot', 'R space only', 'choice', choices=list(Feffit_PlotChoices.keys()),
211 desc='How to plot results for Feff fitting'),
212 CVar('fit_kmin', -1, 'float', min=-1, step=0.1, max=20, desc='k min for EXAFS Fourier transform\n(use -1 for "same as EXAFS")'),
213 CVar('fit_kmax', -1, 'float', min=-1, step=0.1, desc='k max for EXAFS Fourier transform\n(use -1 for "same as EXAFS")'),
214 CVar('fit_dk', -1, 'float', min=-1, step=0.1, desc='window parameter for k->R EXAFS Fourier transform\n(use -1 for "same as EXAFS")'),
215 CVar('fit_kwindow', 'Kaiser-Bessel', 'choice', choices=FT_WINDOWS_AUTO, desc='window type for k->R EXAFS Fourier transform\n(use "Auto" for "same as EXAFS")'),
216 CVar('fit_rmin', -1, 'float', min=-1, step=0.1, max=20, desc='R min for EXAFS Back Fourier transform\n(use -1 for "use Rbkg")'),
217 CVar('fit_rmax', -1, 'float', min=-1, step=0.1, desc='k max for EXAFS Back Fourier transform\n(use -1 for "same as EXAFS")'),
218 CVar('fit_dr', -1, 'float', min=-1, step=0.05, desc='window parameter for EXAFS Back Fourier transform\n(use -1 for "same as EXAFS")'),
219 CVar('fit_rwindow', 'Hanning', 'choice', choices=FT_WINDOWS_AUTO, desc='window type for EXAFS Back Fourier transform\n(use "Auto" for "same as EXAFS")'),
220 ]
223lincombo = [CVar('all_combos', True, 'bool', desc='whether to fit all combinations'),
224 CVar('elo_rel', -40, 'float', desc='low-energy fit range, relative to E0'),
225 CVar('ehi_rel', 100, 'float', desc='high-energy fit range, relative to E0'),
226 CVar('sum_to_one', False, 'bool', desc='whether components high-energy fit range, relative to E0'),
227 CVar('fitspace', 'Normalized μ(E)', 'choice', choices=list(Linear_ArrayChoices.keys()),
228 desc='Array to use for Linear Combinations'),
229 CVar('vary_e0', False, 'bool', desc='whether to vary E0 in the fit'),
230 CVar('show_e0', False, 'bool', desc='whether to show E0 after fit'),
231 CVar('show_fitrange', True, 'bool', desc='whether to show energy range after fit')]
233pca = [CVar('elo_rel', -40, 'float', desc='low-energy fit range, relative to E0'),
234 CVar('ehi_rel', 100, 'float', desc='high-energy fit range, relative to E0'),
235 CVar('fitspace', 'Normalized μ(E)', 'choice', choices=list(Linear_ArrayChoices.keys()),
236 desc='Array to use for Linear Combinations'),
237 CVar('weight_min', -1, 'float', min=-1, step=0.0001, desc='minimum component weight to use\n(use -1 for "auto")'),
238 CVar('max_components', 20, 'int', min=0, desc='maximum number of components use')
239 ]
242prepeaks = [CVar('elo_rel', -20, 'float', step=0.5, desc='low-energy fit range, relative to E0'),
243 CVar('ehi_rel', 0, 'float', step=0.5, desc='high-energy fit range, relative to E0'),
244 CVar('eblo_rel', -8, 'float', step=0.5, desc='low-energy of "baseline skip" range, relative to E0'),
245 CVar('ebhi_rel', -3, 'float', step=0.5, desc='high-energy of "baseline skip" range, relative to E0'),
246 CVar('fitspace', 'Normalized μ(E)', 'choice', choices=list(PrePeak_ArrayChoices.keys()),
247 desc='Array to use for Pre-edge peak fitting')]
249regression = [CVar('elo_rel', -40, 'float', desc='low-energy fit range, relative to E0'),
250 CVar('ehi_rel', 100, 'float', desc='high-energy fit range, relative to E0'),
251 CVar('fitspace', 'Normalized μ(E)', 'choice', choices=list(Linear_ArrayChoices.keys()),
252 desc='Array to use for Linear Regression'),
253 CVar('variable', 'valence', 'string', desc='name of variable to use for regression'),
254 CVar('method', 'LassoLars', 'choice', choices=Regress_Choices,
255 desc='which Regression method to use'),
256 CVar('alpha', -1, 'float', min=0, step=0.01,
257 desc='alpha regularization parameter for LassoLars\n(use -1 for "auto")'),
258 CVar('cv_folds', -1, 'int', min=-1,
259 desc='number of Cross-Validation folds to use (set to -1 for "auto")'),
260 CVar('cv_repeats', -1, 'int', min=-1,
261 desc='number of Cross-Validation repeats to do (set to -1 for "auto")'),
262 CVar('fit_intercept', True, 'bool', desc='whether to fit the intercept with LassoLars'),
263 CVar('auto_scale_pls', True, 'bool', desc='whether to scale data with Partial-Least-Squares')
264 ]
266xasnorm = [CVar('auto_e0', True, 'bool', desc='whether to automatically set E0'),
267 CVar('auto_nnorm', True, 'bool', desc='whether to automatically set normalization polynomial'),
268 CVar('auto_step', True, 'bool', desc='whether to automatically set edge step'),
269 CVar('show_e0', True, 'bool', desc='whether to show E0'),
270 CVar('energy_shift', 0., 'float', desc='value of Energy shift from original data'),
271 CVar('auto_energy_shift', True, 'bool', desc='when changing energy_shift for a Group, also shift \nall other Groups sharing that reference'),
272 CVar('edge', 'K', 'choice', choices=EDGES, desc='symbol of absorption edge'),
273 CVar('pre1', -200, 'float', step=5, desc='low-energy fit range for pre-edge line,\nrelative to E0'),
274 CVar('pre2', -30, 'float', step=5, desc='high-energy fit range for pre-edge line,\nrelative to E0'),
275 CVar('nvict', 0, 'int', min=0, max=3, desc='Victoreen order for pre-edge fitting\n(Energy^(-nvict))'),
276 CVar('show_pre', False, 'bool', desc='whether to show pre-edge energy range (pre1, pre2)'),
277 CVar('norm_method', 'polynomial', 'choice', choices=NORM_METHODS, desc='normalization method'),
278 CVar('nnorm', 'linear', 'choice', choices=list(NNORM_CHOICES.keys()),
279 desc='type of polynomial for normalization'),
280 CVar('norm1', 150, 'float', step=5, desc='low-energy fit range for normalization curve,\nrelative to E0'),
281 CVar('norm2', -1, 'float', step=5, desc='high-energy fit range for normalization curve,\nelative to E0 (set to -1 for "auto")'),
282 CVar('show_norm', False, 'bool', desc='whether to show normalization energy range (norm1, norm2)'),
283 ]
285xydata = [ CVar('scale', 1.0, 'float', step=0.1, desc='scale to use to "normalize" X-Y data'),
286 CVar('xshift', 0.0, 'float', step=0.1, desc='shift X array of X-Y data'),
287 ]
289xrd1d = [ CVar('scale', 1.0, 'float', step=0.1, desc='scale to use to "normalize" 1D XRD data'),
290 ]
292XASCONF = {}
293FULLCONF= {}
295_locals = locals()
297for section in ('main', 'autosave', 'pin', 'plot', 'xasnorm', 'exafs',
298 'feffit', 'prepeaks', 'lincombo', 'pca', 'regression',
299 'xydata', 'xrd1d'):
301 sname = section
302 XASCONF[sname] = {}
303 FULLCONF[sname] = {}
304 for v in _locals[section]:
305 XASCONF[sname][v.name] = v.value
306 FULLCONF[sname][v.name] = v