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

1import wxmplot 

2 

3from larch.site_config import get_homedir 

4from larch.xafs.xafsutils import FT_WINDOWS 

5from larch.utils.physical_constants import ATOM_SYMS 

6 

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

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

9OLDCONF_FILE = 'xas_viewer.conf' 

10CONF_FILE = 'larix.conf' 

11 

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

13 'xtick.labelsize': 9, 

14 'ytick.labelsize': 9, 

15 'axes.labelsize': 9, 

16 'axes.titlesize': 13}) 

17 

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 } 

44 

45# wavelet = 'EXAFS wavelet' 

46 

47FT_WINDOWS_AUTO = ['<Auto>'] 

48FT_WINDOWS_AUTO.extend(FT_WINDOWS) 

49 

50 

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 

58 

59 

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

63 

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

65 

66NNORM_CHOICES = {'auto':None, 'constant':0, 'linear':1, 'quadratic':2, 'cubic':3} 

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

68 

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

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

71 

72 

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

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

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

76 

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

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

79 

80 

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

82 

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 } 

91 

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 

104 

105 if dtype not in Valid_DataTypes: 

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

107 

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

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

110 

111 def __repr__(self): 

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

113 

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

123 

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 ] 

128 

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

133 

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

140 

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 ] 

150 

151 

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

169 

170 

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 ] 

187 

188 

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

198 

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 ] 

206 

207 

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

214 

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 ] 

231 

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

248 

249 CVar('scale', 1.0, 'float', step=0.1, desc='scale to use to "normalize" non-XAS data'), 

250 ] 

251 

252 

253XASCONF = {} 

254FULLCONF= {} 

255 

256_locals = locals() 

257 

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