Coverage for /Users/Newville/Codes/xraylarch/larch/wxxas/config.py: 96%
69 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
1import wxmplot
3from larch.site_config import get_homedir
4from larch.xafs.xafsutils import FT_WINDOWS
5from larch.utils.physical_constants import ATOM_SYMS
7ATSYMS = ['?'] + ATOM_SYMS[:98]
8EDGES = ['K', 'L3', 'L2', 'L1', 'M5', 'M4', 'M3', 'N7']
9OLDCONF_FILE = 'xas_viewer.conf'
10CONF_FILE = 'larix.conf'
12wxmplot.config.Themes['fivethirtyeight'].update({'legend.fontsize': 10,
13 'xtick.labelsize': 9,
14 'ytick.labelsize': 9,
15 'axes.labelsize': 9,
16 'axes.titlesize': 13})
18ARRAYS = {'mu': 'Raw \u03BC(E)',
19 'norm': 'Normalized \u03BC(E)',
20 'flat': 'Flattened \u03BC(E)',
21 'norm+flat': 'Normalized + Flattened \u03BC(E)',
22 'prelines': '\u03BC(E) + Pre-/Post-edge',
23 'mback_norm': '\u03BC(E) + MBACK \u03BC(E)',
24 'mback_poly': 'MBACK + Poly Normalized',
25 'i0': 'I0(E)',
26 'norm+i0': 'Normalized \u03BC(E) + I0(E)',
27 'dmude': 'd\u03BC(E)/dE ',
28 'norm+dmude': 'Normalized \u03BC(E) + d\u03BC(E)/dE',
29 'd2mude': 'd^2\u03BC(E)/dE^2',
30 'norm+d2mude': 'Normalized \u03BC(E) + d^2\u03BC(E)/dE^2',
31 'deconv': 'Deconvolved \u03BC(E)',
32 'chi': '\u03c7(k)',
33 'chi0': '\u03c7(k)',
34 'chi1': 'k \u03c7(k)',
35 'chi2': 'k^2 \u03c7(k)',
36 'chi3': 'k^3 \u03c7(k)',
37 'chir_mag': '|\u03c7(R)|',
38 'chir_re': 'Re[\u03c7(R)]',
39 'chir_mag+chir_re': '|\u03c7(R)| + Re[\u03c7(R)]',
40 'chir_re_chir_im': 'Re[\u03c7(R)] + Im[\u03c7(R)]',
41 'chiq': 'Filtered \u03c7(k)',
42 'noplot': '<no plot>',
43 }
45# wavelet = 'EXAFS wavelet'
47FT_WINDOWS_AUTO = ['<Auto>']
48FT_WINDOWS_AUTO.extend(FT_WINDOWS)
51def make_array_choice(opts):
52 """make (ordered) dict of {Array Description: varname}"""
53 out = {}
54 for n in opts:
55 if n in ARRAYS:
56 out[ARRAYS[n]] = n
57 return out
60Linear_ArrayChoices = make_array_choice(['norm', 'flat', 'dmude', 'chi0', 'chi1', 'chi2'])
61PrePeak_ArrayChoices = make_array_choice(['norm', 'flat', 'deconv'])
62Regress_Choices = ['Partial Least Squares', 'LassoLars']
64PlotWindowChoices = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
66NNORM_CHOICES = {'auto':None, 'constant':0, 'linear':1, 'quadratic':2, 'cubic':3}
67NORM_METHODS = ('polynomial', 'mback')
69ATHENA_CLAMPNAMES = {'none': 0, 'slight': 1, 'weak': 5, 'medium': 20,
70 'strong': 100, 'rigid': 500}
73Feffit_KWChoices = {'1': '1', '2': '2', '3': '3',
74 '2 and 3': '[2, 3]',
75 '1, 2, and 3': '[2, 1, 3]'}
77Feffit_SpaceChoices = {'R space':'r', 'k space':'k', 'wavelet': 'w'}
78Feffit_PlotChoices = {'K and R space': 'k+r', 'R space only': 'r'}
81Valid_DataTypes = ('string', 'float', 'int', 'bool', 'choice', 'path')
83PANELS = {'exafs': 'EXAFS Background Subtraction and Fourier Transforms',
84 'feffit': 'Feff Fitting of EXAFS Paths',
85 'lincombo': 'Linear Combination Analysis',
86 'pca': 'Principal Component Analysis',
87 'prepeaks': 'Pre-edge Peak Analysis',
88 'regression': 'Regression and Feature Selection',
89 'xasnorm': 'XAS Normalization',
90 }
92class CVar:
93 """configuration variable"""
94 def __init__(self, name, value, dtype, choices=None, desc='a variable',
95 min=None, max=None, step=1):
96 self.name = name
97 self.value = value
98 self.dtype = dtype
99 self.choices = choices
100 self.desc = desc
101 self.min = min
102 self.max = max
103 self.step = step
105 if dtype not in Valid_DataTypes:
106 raise ValueError(f"unknown configuration type '{dtype}' for '{name}'")
108 if dtype == 'choice' and self.choices is None:
109 raise ValueError(f"choice configuration type must have choices for '{name}'")
111 def __repr__(self):
112 return f"CVar('{self.name}', {self.value!r}, '{self.dtype}')"
114##
115## sections
116##
117CONF_SECTIONS = {k:v for k, v in PANELS.items()}
118CONF_SECTIONS.update({'main': 'Main program configuration',
119 'pin': 'Pin icon to select points from plots',
120 'plot': 'General Plotting',
121 'autosave': 'Automatic saving of Session files',
122 })
124main = [CVar('chdir_on_fileopen', True, 'bool', desc='whether to change working directory when opening a file'),
125 CVar('workdir', get_homedir(), 'path', desc='starting working directory'),
126 CVar('use_last_workdir', True, 'bool', desc='whehter to use the working directory of the last session\nor always start in workdir'),
127 ]
129autosave = [CVar('savetime', 900, 'int', min=1, step=30, desc='time (in sec) between auto-saving Session files'),
130 CVar('nhistory', 5, 'int', min=0, desc='number of auto-saved Session files to keep per session'),
131 CVar('maxfiles', 10, 'int', min=0, desc='maximum number of auto-saved Session files to keep from all sessions'),
132 CVar('fileroot', 'autosave', 'string', desc='filename prefix for auto-saved Session files')]
134pin = [CVar('style', 'pin first', 'choice', choices=['pin first', 'plot first'],
135 desc='whether to click on pin first, then plot or plot first, then pin'),
136 CVar('min_time', 2.0, 'float', min=0, max=60,
137 desc='minimum time (seconds) between clicking on the pin and reporting a value,\nallowing multiple clicks on the plot in that time'),
138 CVar('max_time', 15.0, 'float', min=1, max=300,
139 desc='maximum time (seconds) after clicking on the pin to click on plot.\nWill report last saved value')]
141plot = [CVar('theme', 'light', 'choice', choices=list(wxmplot.config.Themes.keys()),
142 desc='plotting theme for colors and "look and feel"'),
143 CVar('height', 550, 'int', min=100, desc='height of main plot window (in pixels)'),
144 CVar('width', 600, 'int', min=100, desc='width of main plot window (in pixels)'),
145 CVar('linewidth', 3.0, 'float', min=0, step=0.5, desc='line width for each trace (in pixels)'),
146 CVar('markersize', 4.0, 'float', min=0, step=0.5, desc='size of plot markers (in pixels)'),
147 CVar('show_grid', True, 'bool', desc='whether to show grid lines'),
148 CVar('show_fullbox', True, 'bool', desc='whether to show a full box around plot,\nor only left and bottom axes'),
149 ]
152exafs = [CVar('rbkg', 1.0, 'float', min=0, step=0.1, max=10, desc='R value separating background from EXAFS signal'),
153 CVar('bkg_kmin', 0.0, 'float', min=0, step=0.1, max=10, desc='k min for background subtraction'),
154 CVar('bkg_kmax', -1, 'float', min=-1, step=0.1, desc='k max for background subtraction\n(use -1 for "auto")'),
155 CVar('bkg_kweight', 1, 'float', min=0, step=1, max=10, desc='k weight for background subtraction'),
156 CVar('bkg_clamplo', 1, 'float', min=0, step=5, desc='low-k clamp for background subtraction'),
157 CVar('bkg_clamphi', 20, 'float', min=0, step=5, desc='high-k clamp for background subtraction'),
158 CVar('fft_kmin', 2.0, 'float', min=0, step=0.1, max=50, desc='k min for EXAFS Fourier transform'),
159 CVar('fft_kmax', -1, 'float', min=-1, step=0.1, desc='k max for EXAFS Fourier transform\n(use -1 for "auto")'),
160 CVar('fft_kweight', 2, 'float', min=0, step=1, max=10, desc='k weight for EXAFS Fourier transform'),
161 CVar('fft_dk', 4, 'float', min=0, step=0.1, desc='window parameter for k->R EXAFS Fourier transform'),
162 CVar('fft_kwindow', 'Kaiser-Bessel', 'choice', choices=FT_WINDOWS, desc='window type for k->R EXAFS Fourier transform'),
163 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")'),
164 CVar('fft_rmax', 5.0, 'float', min=0, step=0.1, desc='k max for EXAFS Back Fourier transform'),
165 CVar('fft_dr', 0.25, 'float', min=0, step=0.05, desc='window parameter for EXAFS Back Fourier transform'),
166 CVar('fft_rwindow', 'Hanning', 'choice', choices=FT_WINDOWS, desc='window type for EXAFS Back Fourier transform'),
167 CVar('fft_rmaxout', 12.0, 'float', min=0, step=0.5, desc='maximum output R value for EXAFS Fourier transform'),
168 CVar('plot_rmax', 8.0, 'float', min=0, step=0.5, desc='maximum R value for EXAFS chi(R) plots')]
171feffit = [CVar('plot_paths', True, 'bool', desc='Whether to plot individual paths in results for Feff fitting'),
172 CVar('fit_kwstring', '2', 'choice', choices=list(Feffit_KWChoices.keys()),
173 desc='k weight to use for Feff fitting'),
174 CVar('fit_space', 'R', 'choice', choices=list(Feffit_SpaceChoices.keys()),
175 desc='Fourier space to use for Feff fitting'),
176 CVar('fit_plot', 'R space only', 'choice', choices=list(Feffit_PlotChoices.keys()),
177 desc='How to plot results for Feff fitting'),
178 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")'),
179 CVar('fit_kmax', -1, 'float', min=-1, step=0.1, desc='k max for EXAFS Fourier transform\n(use -1 for "same as EXAFS")'),
180 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")'),
181 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")'),
182 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")'),
183 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")'),
184 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")'),
185 CVar('fit_rwindow', 'Hanning', 'choice', choices=FT_WINDOWS_AUTO, desc='window type for EXAFS Back Fourier transform\n(use "Auto" for "same as EXAFS")'),
186 ]
189lincombo = [CVar('all_combos', True, 'bool', desc='whether to fit all combinations'),
190 CVar('elo_rel', -40, 'float', desc='low-energy fit range, relative to E0'),
191 CVar('ehi_rel', 100, 'float', desc='high-energy fit range, relative to E0'),
192 CVar('sum_to_one', False, 'bool', desc='whether components high-energy fit range, relative to E0'),
193 CVar('fitspace', 'Normalized μ(E)', 'choice', choices=list(Linear_ArrayChoices.keys()),
194 desc='Array to use for Linear Combinations'),
195 CVar('vary_e0', False, 'bool', desc='whether to vary E0 in the fit'),
196 CVar('show_e0', False, 'bool', desc='whether to show E0 after fit'),
197 CVar('show_fitrange', True, 'bool', desc='whether to show energy range after fit')]
199pca = [CVar('elo_rel', -40, 'float', desc='low-energy fit range, relative to E0'),
200 CVar('ehi_rel', 100, 'float', desc='high-energy fit range, relative to E0'),
201 CVar('fitspace', 'Normalized μ(E)', 'choice', choices=list(Linear_ArrayChoices.keys()),
202 desc='Array to use for Linear Combinations'),
203 CVar('weight_min', -1, 'float', min=-1, step=0.0001, desc='minimum component weight to use\n(use -1 for "auto")'),
204 CVar('max_components', 20, 'int', min=0, desc='maximum number of components use')
205 ]
208prepeaks = [CVar('elo_rel', -20, 'float', step=0.5, desc='low-energy fit range, relative to E0'),
209 CVar('ehi_rel', 0, 'float', step=0.5, desc='high-energy fit range, relative to E0'),
210 CVar('eblo_rel', -8, 'float', step=0.5, desc='low-energy of "baseline skip" range, relative to E0'),
211 CVar('ebhi_rel', -3, 'float', step=0.5, desc='high-energy of "baseline skip" range, relative to E0'),
212 CVar('fitspace', 'Normalized μ(E)', 'choice', choices=list(PrePeak_ArrayChoices.keys()),
213 desc='Array to use for Pre-edge peak fitting')]
215regression = [CVar('elo_rel', -40, 'float', desc='low-energy fit range, relative to E0'),
216 CVar('ehi_rel', 100, 'float', desc='high-energy fit range, relative to E0'),
217 CVar('fitspace', 'Normalized μ(E)', 'choice', choices=list(Linear_ArrayChoices.keys()),
218 desc='Array to use for Linear Regression'),
219 CVar('variable', 'valence', 'string', desc='name of variable to use for regression'),
220 CVar('method', 'LassoLars', 'choice', choices=Regress_Choices,
221 desc='which Regression method to use'),
222 CVar('alpha', -1, 'float', min=0, step=0.01,
223 desc='alpha regularization parameter for LassoLars\n(use -1 for "auto")'),
224 CVar('cv_folds', -1, 'int', min=-1,
225 desc='number of Cross-Validation folds to use (set to -1 for "auto")'),
226 CVar('cv_repeats', -1, 'int', min=-1,
227 desc='number of Cross-Validation repeats to do (set to -1 for "auto")'),
228 CVar('fit_intercept', True, 'bool', desc='whether to fit the intercept with LassoLars'),
229 CVar('auto_scale_pls', True, 'bool', desc='whether to scale data with Partial-Least-Squares')
230 ]
232xasnorm = [CVar('auto_e0', True, 'bool', desc='whether to automatically set E0'),
233 CVar('auto_step', True, 'bool', desc='whether to automatically set edge step'),
234 CVar('show_e0', True, 'bool', desc='whether to show E0'),
235 CVar('energy_shift', 0., 'float', desc='value of Energy shift from original data'),
236 CVar('auto_energy_shift', True, 'bool', desc='when changing energy_shift for a Group, also shift \nall other Groups sharing that reference'),
237 CVar('edge', 'K', 'choice', choices=EDGES, desc='symbol of absorption edge'),
238 CVar('pre1', -200, 'float', step=5, desc='low-energy fit range for pre-edge line,\nrelative to E0'),
239 CVar('pre2', -30, 'float', step=5, desc='high-energy fit range for pre-edge line,\nrelative to E0'),
240 CVar('nvict', 0, 'int', min=0, max=3, desc='Victoreen order for pre-edge fitting\n(Energy^(-nvict))'),
241 CVar('show_pre', False, 'bool', desc='whether to show pre-edge energy range (pre1, pre2)'),
242 CVar('norm_method', 'polynomial', 'choice', choices=NORM_METHODS, desc='normalization method'),
243 CVar('nnorm', 'auto', 'choice', choices=list(NNORM_CHOICES.keys()),
244 desc='type of polynomial for normalization'),
245 CVar('norm1', 150, 'float', step=5, desc='low-energy fit range for normalization curve,\nrelative to E0'),
246 CVar('norm2', -1, 'float', step=5, desc='high-energy fit range for normalization curve,\nelative to E0 (set to -1 for "auto")'),
247 CVar('show_norm', False, 'bool', desc='whether to show normalization energy range (norm1, norm2)'),
249 CVar('scale', 1.0, 'float', step=0.1, desc='scale to use to "normalize" non-XAS data'),
250 ]
253XASCONF = {}
254FULLCONF= {}
256_locals = locals()
258for section in ('main', 'autosave', 'pin', 'plot', 'xasnorm', 'exafs',
259 'feffit', 'prepeaks', 'lincombo', 'pca', 'regression'):
260 sname = section
261 XASCONF[sname] = {}
262 FULLCONF[sname] = {}
263 for v in _locals[section]:
264 XASCONF[sname][v.name] = v.value
265 FULLCONF[sname][v.name] = v