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

1from collections import namedtuple 

2 

3import wxmplot 

4 

5from larch.site_config import get_homedir 

6from larch.xafs.xafsutils import FT_WINDOWS 

7from larch.utils.physical_constants import ATOM_SYMS 

8 

9ATSYMS = ['?'] + ATOM_SYMS[:98] 

10EDGES = ['K', 'L3', 'L2', 'L1', 'M5', 'M4', 'M3', 'N7'] 

11OLDCONF_FILE = 'xas_viewer.conf' 

12CONF_FILE = 'larix.conf' 

13 

14wxmplot.config.Themes['fivethirtyeight'].update({'legend.fontsize': 10, 

15 'xtick.labelsize': 9, 

16 'ytick.labelsize': 9, 

17 'axes.labelsize': 9, 

18 'axes.titlesize': 13}) 

19 

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 } 

46 

47# wavelet = 'EXAFS wavelet' 

48 

49FT_WINDOWS_AUTO = ['<Auto>'] 

50FT_WINDOWS_AUTO.extend(FT_WINDOWS) 

51 

52 

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 

60 

61 

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

65 

66PlotWindowChoices = ['1', '2', '3', '4', '5', '6', '7', '8', '9'] 

67 

68NNORM_CHOICES = {'constant':0, 'linear':1, 'quadratic':2, 'cubic':3} 

69NNORM_STRINGS = {int(v): k for k, v in NNORM_CHOICES.items()} 

70 

71NORM_METHODS = ('polynomial', 'mback') 

72 

73ATHENA_CLAMPNAMES = {'none': 0, 'slight': 1, 'weak': 5, 'medium': 20, 

74 'strong': 100, 'rigid': 500} 

75 

76 

77Feffit_KWChoices = {'1': '1', '2': '2', '3': '3', 

78 '2 and 3': '[2, 3]', 

79 '1, 2, and 3': '[2, 1, 3]'} 

80 

81Feffit_SpaceChoices = {'R space':'r', 'k space':'k', 'wavelet': 'w'} 

82Feffit_PlotChoices = {'K and R space': 'k+r', 'R space only': 'r'} 

83 

84Valid_DataTypes = ('string', 'float', 'int', 'bool', 'choice', 'path') 

85 

86 

87AnalysisTab = namedtuple('AnalysisTab', ('title', 'constructor', 'desc')) 

88 

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} 

115 

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 } 

125 

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 

138 

139 if dtype not in Valid_DataTypes: 

140 raise ValueError(f"unknown configuration type '{dtype}' for '{name}'") 

141 

142 if dtype == 'choice' and self.choices is None: 

143 raise ValueError(f"choice configuration type must have choices for '{name}'") 

144 

145 def __repr__(self): 

146 return f"CVar('{self.name}', {self.value!r}, '{self.dtype}')" 

147 

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

157 

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 ] 

162 

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

167 

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

174 

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 ] 

184 

185 

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

203 

204 

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 ] 

221 

222 

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

232 

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 ] 

240 

241 

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

248 

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 ] 

265 

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 ] 

284 

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 ] 

288 

289xrd1d = [ CVar('scale', 1.0, 'float', step=0.1, desc='scale to use to "normalize" 1D XRD data'), 

290 ] 

291 

292XASCONF = {} 

293FULLCONF= {} 

294 

295_locals = locals() 

296 

297for section in ('main', 'autosave', 'pin', 'plot', 'xasnorm', 'exafs', 

298 'feffit', 'prepeaks', 'lincombo', 'pca', 'regression', 

299 'xydata', 'xrd1d'): 

300 

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